[英]When will an async await method return from the UI-Thread? At the first await or at the inner await?
我在 UI 线程上的 WPF 中使用异步等待。 我有一个关于 async await 在特定情况下如何工作的问题。 我将尝试用一个例子来解释它。
假设我有带有单击事件处理程序ButtonA_Click()
的按钮 A 和带有ButtonB_Click()
的按钮 B。 点击处理程序将检查RunLoop()
方法是否仍在运行。 如果它没有运行,它们会启动RunLoop()
。
await RunLoop()
时,事件处理程序是否会从 UI 线程返回?RunLoop()
的(内部)等待处返回,因为它可以在Runloop()
的开头执行同步代码( _isStopped = false;
)。 如果 1. 为真,它可能会导致赛车状况,或者? 当同时调用两个点击处理程序时,它们将在 UI-Thread 上紧接着运行。 因此,第二个事件处理程序可能会在第一次执行 RunLoop() 之前运行。 在这种情况下, _isStopped 对于第二个事件处理程序仍然是错误的,它也会启动一个RunLoop()
。 因此 2 RunLoop()
将处于活动状态。 那是对的吗?
(PS:我知道,如果 1. 是这种情况,我可以通过将_isStopped = false
放入点击处理程序来解决这个问题,但这个问题更多地是关于了解当方法以这种方式嵌套时异步等待是如何工作的)。
private bool _isStopped = true;
private List<Customer> _customers; // will be filled from somewhere else
public async void ButtonA_Click()
{
// do some stuff synchronously
if (_isStopped)
await RunLoop();
}
public async void ButtonB_Click()
{
// do some stuff synchronously
if (_isStopped)
await RunLoop();
}
private async Task RunLoop()
{
_isStopped = false;
while (_customers.Any())
{
_customers.Remove(...);
await Task.Run(() => ProcessStuff());
}
_isStopped = true;
}
这些链接帮助我更好地理解它
当await
被赋予一个不完整的Task
时,控制权返回给调用方法。
这意味着首先,必须给await
一个Task
,这意味着您调用的方法必须在await
执行任何操作之前返回。 其次, Task
必须是不完整的。 如果await
看到一个完整的Task
,则同步恢复执行。
在您的情况下,假设ButtonA_Click()
运行:
ButtonA_Click()
开始同步运行。RunLoop()
被执行,它开始同步运行。Task.Run
被执行,这将返回一个不完整的Task
。RunLoop()
中的await
看到不完整的Task
并返回它自己的不完整Task
。ButtonA_Click()
中的await
会看到不完整的Task
并且通常会返回Task
,但该方法是void
,因此它什么也不返回。ButtonA_Click()
的东西。Microsoft 有一些关于使用 async 和 await 进行异步编程的好文章,值得一读。
这将是第二个选择。 async
方法中的代码同步运行,直到遇到等待未完成Task
的await
语句。
请注意,如果所有等待的Tasks
在等待之前完成,或者没有任何代码实际上需要await
语句,它可能会一直同步运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.