C# 理解WebClient UploadString()与UploadStringTaskAsync的异步
当异步与同步在非可视环境中运行时,例如Azure Worker或Web Api控制器,我很难理解它的好处:C# 理解WebClient UploadString()与UploadStringTaskAsync的异步,c#,.net,asynchronous,task-parallel-library,async-await,C#,.net,Asynchronous,Task Parallel Library,Async Await,当异步与同步在非可视环境中运行时,例如Azure Worker或Web Api控制器,我很难理解它的好处: using (var wc = new WebClient()) { wc.UploadString(uri, message); // vs. await wc.UploadStringTaskAsync(uri, message); } 难道主线程不需要等待,因此对性能没有影响吗?除了UI作业还有什么 难道主线程不需要等待,因此它不会 性能差异?除了UI作业还
using (var wc = new WebClient())
{
wc.UploadString(uri, message);
// vs.
await wc.UploadStringTaskAsync(uri, message);
}
难道主线程不需要等待,因此对性能没有影响吗?除了UI作业还有什么
难道主线程不需要等待,因此它不会
性能差异?除了UI作业还有什么
例如,当您使用Web API时,ASP.NET线程池会为您提供一个线程,您可以在该线程上执行代码。当您等待一个异步方法时,您将该线程释放回池中,以允许处理更多连接。异步方法将控制权交还给调用方法(如果是顶级处理程序,则交给线程池),现在线程可以自由处理更多工作。在同步版本中,您只需阻塞线程,直到IO完成
这样,即使没有涉及UI,你也可以让你的应用程序更具响应性,让你同时处理更多的工作。确实,即使你使用的是
async
也有一些主线程在某处运行。好处是,您可以同时执行多个异步操作,而不会阻塞任何线程。这增加了您的可伸缩性,因为您可以用更少的资源处理更多的工作
想象一下,您使用的不是单个WebClient
,而是1000。在某个地方仍然有一个主线程,但是您没有在IO上阻塞更多的1000个线程,而是没有使用任何线程
public Task Upload(string message)
{
using (var wc = new WebClient())
{
wc.UploadString(uri, message);
// vs.
await wc.UploadStringTaskAsync(uri, message);
}
}
await Task.WhenAll(messages.Select(message => Upload(message))) // multiple operations. 0 blocked threads.
这意味着只需一个操作,不需要创建额外的线程,就不会有什么不同,对吗?@BenjaminE。如果您的整个应用程序只需要一个线程,并且响应性不是问题,那么是的,没有真正的区别。但是大多数应用程序,尤其是服务器应用程序,并不仅仅使用单个线程。好吧,给定一个Wep Api控制器,它在每个请求中使用一个实例,那么async是否会将任何资源返回到线程池,或者这个控制器实例是否仍然保留线程?正如@YuvalItzchakov所说,您正在从线程池中提供一个线程来处理请求,如果
async
操作不需要该请求,则返回该请求。不过,可能还有一个线程在等待新的请求。