c# - How does control flow when there is synchronous code in awaited function?
问题描述
Say in button click event I have:
await someFn()
And in the someFn
code, I have got some synchronous code and some asynchronous code.
As per online reading on this topic, they all seem to say that when await
is encountered, control immediately goes back the caller (UI thread in this case) while the asynchronous waiting happens.
I haven't come across situation where it is explained what happens when there is some synchronous code just before the async
code in the awaited function. Does the synchronous code execute before passing the control to the caller (UI thread)?
I know that- had it been run using await Task.Run(...)
instead of await someFn()
then it would execute in a separate thread.
解决方案
It is true that "when await is encountered, control immediately goes back the caller", under the condition that the awaitable will not be completed at the await
point. Otherwise (if the awaitable is already completed) the control will stay inside the method, by executing immediately the code that follows the await
.
That's all that influences the behavior of the await
operator: the result of the IsCompleted
property of the awaiter. It doesn't matter if the method that produced the awaitable included synchronous code or not. The await
doesn't know, and doesn't care. A synchronous code block inside the someFn
will indeed make a difference regarding the responsiveness of your application, but that has nothing to do with the await
. To understand why, it may help to rewrite your code in a more verbose but equivalent form. This:
await someFn();
...is equivalent to this:
Task t = someFn();
await t;
The UI of your application will freeze because the someFn()
blocks, not because the await t
blocks. Unless of course you have created some wicked task-like awaitable type, that blocks when the IsCompleted
property of its awaiter is invoked.
推荐阅读
- flutter - 我们必须选择哪个 BuildContext?内层还是外层?
- matlab - MATLAB:表的相等行或字符串的相等字
- java - 工具栏从曲线滚动到正常图像重叠
- mongodb - 我可以将 3.6 次要添加到 2.6 MongoDB 副本集吗
- java - 如何为 Webflux 应用程序包装阻塞 IO 操作
- angular - 在Angular 6中重置反应表单时输入不会禁用
- asp.net-core - 我无法在 .net core 3.1 Web 应用程序中将现有项目(.net core worker service app)添加为 azure webjob
- c++ - 通过迭代器修改不反映
- android - 如何限制用户仅从 Cloud Firestore 检索他们的数据?
- python - 转义空格的问题?系统找不到路径