你可以像这样重构该代码片段:
async Task<bool> WaitForItToWork()
{
bool succeeded = false;
while (!succeeded)
{
succeeded = outcome;
await Task.Delay(1000);
}
return succeeded;
}
显然,它唯一的好处是更有效地利用线程池,因为并不总是需要一个完整的线程来完成延迟。
根据您获取outcome
的方式,可能有更有效的方法使用async/await
完成此任务。通常,您可能会像这样拥有GetOutcomeAsync()
,它会以自然的方式异步地调用Web服务、数据库或套接字,因此您只需执行var outcome = await GetOutcomeAsync()
。
重要的是要考虑到编译器将通过await
行将WaitForItToWork
分成几部分,并继续异步进行的事实。 这里也许是关于如何在内部完成的最好的解释。问题在于,通常在代码的某个点上,您需要对异步任务的结果进行同步。例如:
private void Form1_Load(object sender, EventArgs e)
{
Task<bool> task = WaitForItToWork();
task.ContinueWith(_ => {
MessageBox.Show("WaitForItToWork done:" + task.Result.toString());
}, TaskScheduler.FromCurrentSynchronizationContext());
}
你本可以简单地这样做:
private async void Form1_Load(object sender, EventArgs e)
{
bool result = await WaitForItToWork();
MessageBox.Show("WaitForItToWork done:" + result.toString());
}
然而,这将使Form1_Load
也成为异步方法。
[更新]
以下是我尝试说明在这种情况下async/await
实际上做了什么的内容。我创建了两个相同逻辑的版本,WaitForItToWorkAsync
(使用async/await
)和WaitForItToWorkAsyncTap
(使用TAP模式但不使用async/await
)。第一个版本相当简单,而第二个版本则不同。因此,虽然async/await
在很大程度上是编译器的语法糖,但它使异步代码更容易编写和理解。
bool outcome()
async Task<bool> WaitForItToWorkAsync()
return succeeded;
}
Task<bool> WaitForItToWorkAsyncTap()
, context);
};
closure();
return tcs.Task;
}
private void StartWaitForItToWork()
, TaskScheduler.FromCurrentSynchronizationContext());
WaitForItToWorkAsyncTap().ContinueWith((t) =>
, TaskScheduler.FromCurrentSynchronizationContext());
}
private async Task StartWaitForItToWorkAsync()
关于线程的几句话。这里没有显式地创建任何额外的线程。在内部,Task.Delay()
的实现可能会使用线程池(我怀疑它们使用 计时器队列),但在这个特定的示例中(一个 WinForms 应用程序),await
之后的继续操作将在同一 UI 线程上发生。在其他执行环境中(例如控制台应用程序),它可能会继续在不同的线程上。在我看来,Stephen Cleary 的 这篇文章 是了解 async/await
线程概念的必读之作。
this.WaitForItToWork();
来调用它 - 异步库会为我处理线程吗? - Chrisawait this.WaitForItToWork()
,整个调用链必须重构以支持此操作... 我会详细说明我的答案并提供更多信息。 - noseratio - open to workSleep
这样的东西)。对于await Task.Delay()
最好的类比可能是一个计时器事件。async/await
只是编译器提供的一种语法糖。从某种意义上说,它类似于node.js
,如果你熟悉它的话(尽管Node的javascript缺乏语法方便性 - 一切都通过闭包 - 在C#中使用委托)。 - noseratio - open to work