我已经阅读了asp.net(c#)中异步编程所能找到的所有内容。我已经理解了它应该如何工作以及什么时候应该使用的大部分内容。然而,我发现基本的例子没有按照我的预期运作。如果没有Task.Run
,它似乎并没有实际异步运行。
有人可以告诉我在这个例子中我错过了什么吗?
说代码是这样的
public async Task SubTask2()
{
LongRunningOperation2();
Response.Write("<br>------------------------ Finished -------------------------<br>");
}
private async Task<Boolean> LongRunningOperation1()
{
int counter;
for (counter = 0; counter < 50000; counter++)
{
Response.Write(counter + "<br>");
}
return await Task.FromResult<bool>(true);
}
private async Task<Boolean> LongRunningOperation2()
{
await LongRunningOperation1();
Response.Write("<br>------------------------ Long Task -------------------------<br>");
return true;
}
不应该LongRunningOperation2()
返回SubTask2()
并打印&#34;已完成&#34;在写出数字之前或同时?相反,它打印完毕。使用Task.Run
按预期工作但后来我没有看到永远不使用Task.Run
答案 0 :(得分:1)
async
/ await
模式的设计考虑因素是,有时具有async
签名的代码可能会(立即)同步返回 - 可能是由于缓存或本地数据缓冲(读取)也许是来自套接字的数据,并且剩余的数据要从缓冲区中消耗掉,或者可能是由于IoC等提供了异步签名的同步实现。在这种情况下,整个引擎被设计为通过而不是进行优化来做任何回调,但继续同步运行。这不是边缘情况 - 最近的C#更新扩展这一点通过添加对自定义等待项的支持(特别是:ValueTask<T>
)到使其更加高效在某些事情以同步但非平凡的结果完成的情况下。
异步的目的是促进具有真正异步组件的场景,释放线程以执行比等待异步操作完成更多有用的事情。 不关于并行化。
在您的情况下,您的所有代码实际上都是同步的,因此它会一直持续同步运行。
答案 1 :(得分:0)
首先,您在await
中缺少SubTask2()
,因此它实际上是同步运行的(等待LongRunningOperation2()
完成)。
其次,即使使用异步执行,在LongRunningOperation2()
完成它的工作之前也不会打印“已完成”。使用它的目的是释放线程,因此它可以在此期间做一些其他的工作(例如处理另一个请求)。