问题描述
在异步/等待常见问题解答中,斯蒂芬·图布 说:
In Async/Await FAQ, Stephen Toub says:
awaitable 是任何公开 GetAwaiter
方法的类型,该方法返回一个有效的 awaiter.
...
awaiter 是从 awaitable 的 GetAwaiter
方法返回的任何类型,并且符合特定模式.
所以为了成为等待者,类型应该:
So in order to be an awaiter, a type should:
- 实施
INotifyCompletion
界面. - 提供一个名为
IsCompleted
的布尔属性. - 提供一个无参数的
GetResult
方法,返回void
或TResult
.
- Implement the
INotifyCompletion
interface. - Provide a boolean property called
IsCompleted
. - Provide a parameterless
GetResult
method that returnsvoid
orTResult
.
(我暂时忽略了 ICriticalNotifyCompletion
.)
我知道我提到的页面有一个示例,展示了编译器如何翻译 await 操作,但我仍然很难理解.
I know the page I mentioned has a sample that shows how the compiler translates await operations but I'm stil having a hard time understanding.
当我等待一个等待时,
- 什么时候检查
IsCompleted
?我应该在哪里设置它? - 什么时候调用
OnCompleted
? - 哪个线程调用
OnCompleted
? - 我在不同的示例中看到了直接调用
OnCompleted
的 continuation 参数和使用Task.Run(continuation)
的示例,我应该选择哪个,为什么?
- When is
IsCompleted
checked? Where should I set it? - When is
OnCompleted
called? - Which thread calls
OnCompleted
? - I saw examples of both directly invoking the continuation parameter of
OnCompleted
and usingTask.Run(continuation)
in different examples, which should I go for and why?
推荐答案
为什么需要自定义等待器?
Why would you want a custom awaiter?
可以看到编译器对await
的解释此处.本质上:
You can see the compiler's interpretation of await
here. Essentially:
var temp = e.GetAwaiter();
if (!temp.IsCompleted)
{
SAVE_STATE()
temp.OnCompleted(&cont);
return;
cont:
RESTORE_STATE()
}
var i = temp.GetResult();
从评论中 OnCompleted
应该将其参数安排为异步操作的延续.
Edit from comments: OnCompleted
should schedule its argument as a continuation of the asynchronous operation.
这篇关于虚拟人的自定义等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!