MVVMCross如何在另一个线程上做繁重的工作,而不冻结UI?

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

我正在实现一个

UI
,其中包含我使用
framework MVVMCross
的列表。为了填充列表,我迭代了几个目录以收集特定的
XML documents
。现在我想在不同的线程中外包这个迭代过程,以防止主窗口冻结并显示加载轮或进度条。如果我启动这个函数,我会得到
Exception
,我必须从调度程序线程启动线程,但在我看来,我已经从调度程序线程启动它。我做错了什么?

readonly Dispatcher _dispatcher;


public HomeViewModel(IMvxNavigationService navigationService)
{
    NavigationService = navigationService;
    _dispatcher = Dispatcher.CurrentDispatcher;
}

private async void StartDispatcher()
{
    BackgroundWorker _backgroundWorker = new BackgroundWorker();
    _backgroundWorker.DoWork += _backgroundWorker_DoWork;

    Delegate action = new Action(_backgroundWorker.RunWorkerAsync);
    await _dispatcher.BeginInvoke(action, DispatcherPriority.Normal);
    
}

private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    LoadingProcess();
}



尝试了多种方法来使用调度程序启动线程,但没有任何效果。

c# multithreading user-interface mvvm dispatcher
1个回答
0
投票

在后台工作的典型方式是:

private async void OnSomeTypeOfEvent()
{
    var progress = new Progress<long>(); // optional
    var cts = new CancellationTokenSource(); // optional
    try{
        var result = await Task.Run(() => DoWorkInBackground(progress, cts.Token));
        // Update the UI with the result
    }
    catch(OperationCancelledException){} // ignore
    catch(Exception e){
       // handle failure
    }
    
}
private TResult DoWorkInBackground(IProgress progress, CancellationToken cancel){
    // Do background work work
}

所有带有取消和进度的内容都是可选的,并且要求您有一些控制来报告进度和取消。

您尝试做的事情毫无意义。如果您要求调度程序运行某些内容,它会在 UI 线程上运行它,因此它仍然会阻塞 UI。调度程序的主要目的是当您在后台线程上运行某些内容并且需要在 UI 线程上运行某些内容时。但是,我建议使用异步/等待模式,因为这往往会使代码更易于阅读和理解。

您需要确保

DoWorkInBackground
是线程安全的,并且在没有适当同步的情况下不要使用任何共享的、可变的数据结构。如果可能的话,尽量保持方法“纯粹”。

© www.soinside.com 2019 - 2024. All rights reserved.