Eyv*_*ind 6 .net c# event-handling async-await
如果我将我的事件处理程序声明为async void,它们是由.NET框架同步还是异步调用的?
即,给出以下代码:
async void myButton_click(object sender, EventArgs e) {
do stuff
await longRunning()
do more stuff
}
Run Code Online (Sandbox Code Playgroud)
我可以确定在GUI线程上执行"do stuff"行吗?
Sri*_*vel 10
事件处理程序将被同步调用,并且不等待(等待)直到事件处理程序完成,但等待直到事件处理程序返回.
如果以前的句子足够混乱,我会尽力解释清楚.当执行所有等待点并且已到达方法体的末尾或执行任何return语句时,异步方法完成(忽略异常).但是,只要您找到Task尚未完成的第一个await语句,异步方法就会返回.换句话说,异步方法可以返回几次,但只能完成一次.
所以现在我们知道异步方法何时完成并返回.事件处理程序将假定您的方法一旦返回就完成,而不是在实际完成时.
一旦事件处理程序到达第一个await语句,它将返回,如果有更多方法附加到同一个事件处理程序,它将继续执行它们而不等待异步方法完成.
是的,do stuff如果UI线程触发事件,do more stuff将在UI线程中执行,并且只要longRunning().ConfigureAwait(false)未调用,也将在UI线程中执行yes .
它们将像调用任何其他非async-await方法一样被调用:
Click(this, EventArgs.Empty);
Run Code Online (Sandbox Code Playgroud)
因为这个特定的事件处理程序是一个async方法,所以调用将同步运行,直到await到达 an 为止,其余的将继续。这意味着它do stuff是在 GUI 线程上同步执行的。然后调用者继续前进,而不知道操作async尚未完成。
do more stuff也将在 GUI 线程上执行,但原因不同。在SynchronizationContextGUI 环境中,确保将延续发布到单个 GUI 线程,除非您明确告诉它不要这样做await longRunning().ConfigureAwait(false)