异步不按预期工作

时间:2017-11-14 12:24:38

标签: c# asp.net asynchronous

我已经阅读了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

2 个答案:

答案 0 :(得分:1)

async / await模式的设计考虑因素是,有时具有async签名的代码可能会(立即)同步返回 - 可能是由于缓存或本地数据缓冲(读取)也许是来自套接字的数据,并且剩余的数据要从缓冲区中消耗掉,或者可能是由于IoC等提供了异步签名的同步实现。在这种情况下,整个引擎被设计为通过而不是进行优化来做任何回调,但继续同步运行。这不是边缘情况 - 最近的C#更新扩展这一点通过添加对自定义等待项的支持(特别是:ValueTask<T>)到使其更加高效在某些事情以同步但非平凡的结果完成的情况下。

异步的目的是促进具有真正异步组件的场景,释放线程以执行比等待异步操作完成更多有用的事情。 关于并行化。

在您的情况下,您的所有代码实际上都是同步的,因此它会一直持续同步运行。

答案 1 :(得分:0)

首先,您在await中缺少SubTask2(),因此它实际上是同步运行的(等待LongRunningOperation2()完成)。 其次,即使使用异步执行,在LongRunningOperation2()完成它的工作之前也不会打印“已完成”。使用它的目的是释放线程,因此它可以在此期间做一些其他的工作(例如处理另一个请求)。