C# 理解WebClient UploadString()与UploadStringTaskAsync的异步

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作业还

当异步与同步在非可视环境中运行时,例如Azure Worker或Web Api控制器,我很难理解它的好处:

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
操作不需要该请求,则返回该请求。不过,可能还有一个线程在等待新的请求。