B. *_*all 1 .net c# asynchronous async-await
在我当前的项目中,我有一段代码,在将其简化为我遇到问题的地方后,它看起来像这样:
private async Task RunAsync(CancellationToken cancel)
{
bool finished = false;
while (!cancel.IsCancellationRequested && !finished)
finished = await FakeTask();
}
private Task<bool> FakeTask()
{
return Task.FromResult(false);
}
Run Code Online (Sandbox Code Playgroud)
如果我不等待就使用此代码,无论如何我最终都会阻塞:
// example 1
var task = RunAsync(cancel); // Code blocks here...
... // Other code that could run while RunAsync is doing its thing, but is forced to wait
await task;
// example 2
var task = RunAsync(cancelSource.Token); // Code blocks here...
cancelSource.Cancel(); // Never called
Run Code Online (Sandbox Code Playgroud)
在实际项目中,我实际上并没有使用 FakeTask,通常会有一些 Task.Delay 在那里等待,所以大部分时间代码实际上并没有阻塞,或者只是有限的迭代次数.
然而,在单元测试中,我使用了一个模拟对象,它几乎可以完成 FakeTask 所做的工作,所以当我想查看 RunAsync 是否以我期望的方式响应它的 CancellationToken 被取消时,我被卡住了。
我发现我可以通过await Task.Delay(1)在 RunAsync 的顶部添加例如来解决这个问题,以强制它真正异步运行,但这感觉有点麻烦。有更好的选择吗?
Task.FromResult实际上是同步运行的,就像await Task.Delay(0). 如果您想实际模拟异步代码,请调用Task.Yield(). 这将创建一个可等待任务,该任务在等待时异步返回到当前上下文。
你对做什么有一个不正确的心理图景await。的意思await是:
在您的程序中,“假”等待总是完整的,因此协程永远不会暂停。
有更好的选择吗?
如果您的控制流逻辑要求您暂停协程,则使用Task.Yield.
| 归档时间: |
|
| 查看次数: |
588 次 |
| 最近记录: |