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())一个接一个地在同一个线程上运行。
我该怎么做?
我想让两个方法(1.domaminModel.Load(), 2。UpdateState())一个接一个地在同一个线程上运行。而不是在UI线程
更新,如果你只想让_domainModel.Load
和ImageSelectionViewModel.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));
}