我是ReactiveUI的初学者,并且ReactiveCommand的行为很奇怪。
我想从当前不支持的数据库中查询数据异步操作。由于我们要交换数据库中的带有异步接口的未来,我想将所有内容编写为如果数据库已经允许异步操作。据我所理解这意味着我将数据库调用包装在一个任务。
我有一个绑定到ReactiveCommand和命令的按钮启动数据库查询。查询持续时,我想显示一些一种动画。
问题是无论我如何尝试,查询都会阻止我的UI线程。
这是我的代码的一部分:
public ReactiveCommand<Unit, Unit> StartExportCommand { get; }
//The constructor of my view model
public ExportDataViewModel(IDataRepository dr)
{
this.dr = dr;
//...
StartExportCommand = ReactiveCommand.CreateFromTask(() => StartExport());
//...
}
private async Task StartExport()
{
try
{
Status = "Querying data from database...";
//Interestingly without this call the Status message would not even be shown!
//The delay seems to give the system the opportunity to at least update the
//label in the UI that is bound to "Status".
await Task.Delay(100);
//### This is the call that blocks the UI thread for several seconds ###
var result = await dr.GetValues();
//do something with result...
Status = "Successfully completed";
}
catch(Exception ex)
{
Status = "Failed!";
//do whatever else is necessary
}
}
//This is the GetValues method of the implementation of the IDataRepository.
//The dictionary maps measured values to measuring points but that should not matter here.
//ValuesDto is just some container for the values.
public Task<IDictionary<int, ValuesDto>> GetValues()
{
//...
return Task<IDictionary<int, ValuesDto>>.Factory.StartNew(() =>
{
//### here is where the blocking calls to the database
//### specific APIs take place
return result;
}, TaskCreationOptions.LongRunning);
}
“任务中长期运行的查询。此模式是否有问题,或者我应该采用Observables的其他方式吗?
编辑1
我知道异步!=线程的事实。但是,我认为带有TaskCreationOptions.LongRunning的Task会使阻塞代码在线程池线程上运行。编辑2
按照安迪的建议,我在任务中设置了一个断点,并查看了“调试线程”窗口。它告诉我Task正在工作线程上运行。我的用户界面仍然处于阻止状态。TaskCreationOptions.LongRunning
仅向调度程序提供提示。它不保证有新线程。
尝试使用Task.Run()
来使用将使用线程池的默认调度程序。