这两种异步方法有什么区别?

时间:2016-09-13 18:56:07

标签: c# asynchronous async-await

这两种异步方法有什么区别?如果没有,那么这两种方法在哪种情况下会有所不同?

感谢。

public async Task<int> MyMethod1Async()
{
    return 1;
}

public async Task<int> MyMethod2Async()
{
    return await new Task<int>(() => 1);
}

2 个答案:

答案 0 :(得分:1)

第一种方法返回已完成的任务Result 1

第二种方法返回永远不会完成的Task<int>

答案 1 :(得分:1)

看看这两种方法:

public async Task<int> MyMethod1Async()
{
    return 1;
}

这将同步运行,因为其中没有“await”运算符 - 它只返回1,所以它与你刚刚完成以下操作没有什么不同:

public int MyMethod1()
{
    return 1;
}

以下方法可能更好地说明了异步的不同“类型”之间的差异:

    public async Task<string> MyMethod1Async()
    {
        using (HttpClient client = new HttpClient())
        {
            client.BaseAddress = new Uri("SomeBaseAddress");

            // This will return control to the method's caller until this gets a result from the server
            HttpResponseMessage message = await client.GetAsync("SomeURI");

            // The same as above - returns control to the method's caller until this is done
            string content = await message.Content.ReadAsStringAsync();

            return content;
        }
    }

这样的代码不一定会产生额外的线程(除非这就是微软碰巧实现了那些特定的库调用)。无论哪种方式,await / async 都需要创建其他线程;它可以在同一个线程上异步运行。

我对这个事实的标准说明如下:假设你去一家有10个人的餐馆。当服务员来的时候,他要求订购的第一个人还没准备好;然而,其他9人是。因此,服务员要求其他9个人的订单,然后回到原来的家伙,希望他到那时准备好订购。 (绝对不是这样的情况,他们会得到第二个服务员等待原来的人准备订购,这样做可能不会节省太多时间)。这就是async / await在许多情况下的工作原理(例外,一些任务并行库调用,如Thread.Run(...),实际 在其他线程上执行 - 在我们的插图中,带来第二个服务员 - 所以一定要检查哪个文件是哪个。

您列出的下一个项目将无效,因为您只是创建任务,实际上并没有对它执行任何操作:

public async Task<int> MyMethod2Async()
{
    return await new Task<int>(() => 1);
}

我假设您确实打算做以下事情:

public async Task<int> MyMethod2Async()
{
    return await Task.Run<int>(() => 1);
}

这将在线程池中运行lambda表达式,将控制权返回给MyMethod2Async的调用者,直到lambda表达式有结果,然后一旦得到结果就从lambda表达式返回值。

总而言之,不同之处在于你是否在同一个线程上异步运行(相当于你桌子上的第一个人告诉服务员在其他人订购后再回到他身边)或者你是否正在运行任务在一个单独的线程上。

存在过度简化事物的风险,CPU绑定任务通常应该在后台线程上异步运行。但是,IO绑定任务(或者其他持有主要只是等待来自外部系统的某种结果的情况)通常可以在同一个线程上异步运行;将它放在后台线程上而不是在同一个线程上异步执行它不一定会带来很大的性能提升。