【发布时间】:2020-05-19 04:01:47
【问题描述】:
与Task.Wait() 或Task.Result 相比,await 在 C# 5 中使用 Task 可防止执行等待的线程闲置。相反,使用await 关键字的方法需要是async,这样await 的调用只会使该方法返回一个代表async 方法执行的新任务。
但是当await'ed Task 在async 方法再次收到CPU 时间之前完成时,await 将Task 识别为已完成,因此async 方法将返回@987654335 @object 仅在以后使用。在某些情况下,这可能会晚于可接受的时间,因为开发人员假设await'ing 总是推迟其async 方法中的后续语句可能是一个常见错误。
错误的async 方法的结构可能如下所示:
async Task doSthAsync()
{
var a = await getSthAsync();
// perform a long operation
}
那么有时doSthAsync() 会在很长一段时间后才返回Task。
我知道应该这样写:
async Task doSthAsync()
{
var a = await getSthAsync();
await Task.Run(() =>
{
// perform a long operation
};
}
...或者那个:
async Task doSthAsync()
{
var a = await getSthAsync();
await Task.Yield();
// perform a long operation
}
但我不觉得最后两个模式漂亮,想防止错误发生。我正在开发一个提供getSthAsync 的框架,第一个结构应该是通用的。所以 getSthAsync 应该返回一个 Awaitable ,它总是像 Task.Yield() 返回的 YieldAwaitable 那样产生。
不幸的是,任务并行库提供的大多数功能(如Task.WhenAll(IEnumerable<Task> tasks))仅在Tasks 上运行,因此getSthAsync 的结果应该是Task。
那么是否有可能返回一个总是产生的Task?
【问题讨论】:
标签: c# .net multithreading asynchronous async-await