WPF / ReactiveUI应用程序中的ReactiveCommand阻止UI线程

问题描述 投票:0回答:1

我是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正在工作线程上运行。我的用户界面仍然处于阻止状态。
wpf system.reactive reactiveui
1个回答
0
投票
TaskCreationOptions.LongRunning仅向调度程序提供

提示。它不保证有新线程。

尝试使用Task.Run()来使用将使用线程池的默认调度程序。
© www.soinside.com 2019 - 2024. All rights reserved.