C# 为假人定制可等待的物品

C# 为假人定制可等待的物品,c#,.net,asynchronous,.net-4.5,async-await,C#,.net,Asynchronous,.net 4.5,Async Await,在本书中,Stephen Toub说: waitiable是公开返回有效等待器的getwaitier方法的任何类型。 … 等待者是从等待者的GetAwaiter方法返回的符合特定模式的任何类型 因此,为了成为等待者,类型应该: 实现接口 提供名为IsCompleted的布尔属性 提供一个无参数的GetResult方法,该方法返回void或TResult (我暂时忽略ICriticalNotifyCompletion) 我知道我提到的页面有一个示例,显示了编译器如何翻译等待操作,但我仍然很难理

在本书中,Stephen Toub说:

waitiable是公开返回有效等待器的
getwaitier
方法的任何类型。

等待者是从等待者的
GetAwaiter
方法返回的符合特定模式的任何类型

因此,为了成为等待者,类型应该:

  • 实现接口
  • 提供名为
    IsCompleted
    的布尔属性
  • 提供一个无参数的
    GetResult
    方法,该方法返回
    void
    TResult
(我暂时忽略
ICriticalNotifyCompletion

我知道我提到的页面有一个示例,显示了编译器如何翻译等待操作,但我仍然很难理解

当我等待一个等待的时刻

  • 何时检查
    IsCompleted
    ?我应该把它放在哪里
  • 何时调用
    OnCompleted
  • 哪个线程调用
    OnCompleted
  • 我在不同的示例中看到了直接调用
    OnCompleted
    的continuation参数和使用
    Task.Run(continuation)
    的示例,我应该选择哪一个,为什么

您为什么需要定制等待者

您可以看到编译器对
wait
的解释。基本上:

var temp = e.GetAwaiter();
if (!temp.IsCompleted)
{
  SAVE_STATE()
  temp.OnCompleted(&cont);
  return;

cont:
  RESTORE_STATE()
}
var i = temp.GetResult();

从注释编辑:
OnCompleted
应将其参数安排为异步操作的延续。

在绝大多数情况下,作为开发人员,您不必担心这一点。使用
async
wait
关键字,编译器和运行时将为您处理所有这些

回答您的问题:

代码检查何时完成?我应该把它放在哪里

当任务完成了它正在做的事情时,任务应该设置
IsCompleted
。例如,如果任务正在从文件加载数据,
IsCompleted
在加载数据并且调用方可以访问数据时应返回true

它何时调用OnCompleted

OnCompleted通常包含调用者提供的委托,以便在任务完成时执行

它是并行调用OnCompleted还是应该调用代码 内部未完成是异步的吗

OnCompleted中的代码应该是线程无关的(不管从哪个线程调用它)。这对于更新单线程单元中的COM对象(如Metro/Windows8/Windows应用商店应用程序中的任何UI类)可能会有问题。它不必是异步的,但可能包含异步代码

我看到了直接调用OnCompleted的continuation参数的示例 在不同的例子中使用Task.Run(continuation),我应该选择哪一个,什么时候


尽可能使用
async
/
wait
。否则,请使用Task.Run()或Task.Wait(),因为它们遵循大多数人习惯的顺序编程模型。可能仍然需要使用continuations,特别是在你有公寓问题的Metro应用程序中。

没有特别的原因,我只是想知道它是如何工作的。虽然我仍然没有得到编译器对wait(抱歉)的解释,但它是并行调用OnCompleted还是应该提供异步实现?(顺便问一下,你什么时候会做一些等待的套接字文章?
OnCompleted
用于将该方法的其余部分安排为继续。因此,您的实现只需将其作为异步操作的延续添加。我正在研究等待的插座…:)好吧,等待者必须在某处运行延续。如果您不关心同步上下文,那么使用
Task.Run()
可能有意义。忽略上下文是不寻常的,但如果这是一种常见情况,那么您就不会首先创建自定义等待程序。@svick:好的,我可以从中看出原因。
Set在任务完成时完成。
那么什么时候开始做它应该做的事情呢?在构造函数中?在
OnCompleted
?等待程序应等待IsCompleted为true且调用了OnCompleted。任务应该通过任何适当的方式完成它需要完成的任务,通常是在不同的线程上和/或使用线程池。@ŞafakGür这取决于等待者应该做什么。但是一个构造器听起来是一个合理的选择。FWIW,我发现他的“等待任何东西”帖子在这个层面上很有帮助@詹姆斯:很好的参考资料,谢谢。@JamesManning链接已过期,请参阅更新: