using async and await

本文关键字:await and async using | 更新日期: 2023-09-27 17:54:41

    public async override void InitData()
    {
        _domainModel = new DomainModel()
        ProgressIndicatorViewModel.Start();
        _State = Getstate();
        await _domainModel.Load(_State, ProgressIndicatorViewModel); //returns a task
        ImageSelectionViewModel.UpdateState(_State); //returns void not a task!
        ProgressIndicatorViewModel.Stop();
        DispatcherHelper.UIDispatcher.Invoke(() => ImageSelectionViewModel.RefreshImages(_imageList));
    }

我想让两个方法(1.domaminModel.Load(), 2。UpdateState())一个接一个地在同一个线程上运行。

我该怎么做?

using async and await

我想让两个方法(1.domaminModel.Load(), 2。UpdateState())一个接一个地在同一个线程上运行。而不是在UI线程

更新,如果你只想让_domainModel.LoadImageSelectionViewModel.UpdateState在一个单独的非ui线程上运行,那么就这样做:

public async override void InitData()
{
    _domainModel = new DomainModel()
    ProgressIndicatorViewModel.Start();
    _State = Getstate();
    await Task.Run(async () =>
    { 
        await _domainModel.Load(_State, ProgressIndicatorViewModel))
        ImageSelectionViewModel.UpdateState(_State); //returns void not a task!
    });
    ProgressIndicatorViewModel.Stop();
    ImageSelectionViewModel.RefreshImages(_imageList);
}

注意需要DispatcherHelper.UIDispatcher.Invoke()包装器。


如果您希望_domainModel.Load之后的InitData的其余部分在单独的线程上运行:

public async override void InitData()
{
    _domainModel = new DomainModel()
    ProgressIndicatorViewModel.Start();
    _State = Getstate();
    await Task.Run(() => _domainModel.Load(_State, 
        ProgressIndicatorViewModel)).ConfigureAwait(false);
    ImageSelectionViewModel.UpdateState(_State); //returns void not a task!
    DispatcherHelper.UIDispatcher.Invoke(() =>
    {
        ProgressIndicatorViewModel.Stop();
        ImageSelectionViewModel.RefreshImages(_imageList)
    });
}

注意Task.Run将自动为您打开(Task<Task<T>>的)嵌套任务。此外,您可能需要将ProgressIndicatorViewModel.Stop()移动到Dispatcher.Invoke中。

根据_domainModel.Load内部的内容,您甚至可能不需要Task.Run:

await _domainModel.Load(_State, 
    ProgressIndicatorViewModel).ConfigureAwait(false);

顺便说一句,你应该在你的async void InitData方法中处理异常。

考虑以下代码:

public async void Sample()
{
     DoOne();
     await DoTwo();
     DoThree();
     Dispather.BeginInvoke(() => DoFour());
}

DoOne将不会在UI Thread(!)中执行,它的线程将是一个调用方法Sample()命名为 caller Thread 的线程

在大多数情况下,在客户端调用线程是UI线程,因为大多数代码是由用户操作(如鼠标点击)调用的,但它不是一个固定的行为。

DoTwo将在一个单独的线程中执行,很明显,它不会在调用线程中执行。

DoThree将在调用者线程中执行

DoFour将在UI Thread执行,这与什么是调用线程无关。

所以@usr的评论是完全错误的。

要实现您的目标,更改您的代码如下:

public async override void InitData()
    {
        _domainModel = new DomainModel()
        ProgressIndicatorViewModel.Start();
        _State = Getstate();
        await Task.Factory.StartNew(() => {
             _domainModel.Load(_State, ProgressIndicatorViewModel).ContinueWith(() => {
             ImageSelectionViewModel.UpdateState(_State); }); 
           };
        ProgressIndicatorViewModel.Stop();
        DispatcherHelper.UIDispatcher.Invoke(() => ImageSelectionViewModel.RefreshImages(_imageList));
    }