这两种异步方法的区别是什么?
本文关键字:是什么 区别 两种 异步方法 | 更新日期: 2023-09-27 18:06:47
这两种异步方法有什么区别?如果没有,这两种方法在什么情况下会不同?
谢谢。
public async Task<int> MyMethod1Async()
{
return 1;
}
public async Task<int> MyMethod2Async()
{
return await new Task<int>(() => 1);
}
看一下这两种方法:
public async Task<int> MyMethod1Async()
{
return 1;
}
这将同步运行,因为其中没有"await"操作符-它只是返回1,所以它与您刚刚执行的操作没有什么不同:
public int MyMethod1()
{
return 1;
}
下面的方法可能更好地说明了async的不同"类型"之间的区别:
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在很多情况下的工作方式(例外的是一些Task Parallel库调用,比如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绑定的任务(或者其他等待外部系统某种结果的情况)通常可以在同一个线程上异步运行;与在同一线程上异步执行相比,将其放在后台线程上并不一定会有很大的性能改进。
第一个方法返回一个Result
为1
的已经完成的任务。
第二个方法返回一个永远不会完成的Task<int>
。