我通常试图了解有关异步编程的一些知识。 在C#中,似乎每个人现在都在使用异步等待语法糖来进行受IO约束的异步操作。
我的问题是:通过编写一个异步包装函数,到目前为止,任何已绑定到IO的操作(如文件读取,http请求等)都可以变为asnync吗?
还是因为底层的“旧”实现(如果同步)根本没有帮助? 曾经等待的线程会不会被释放?
有人吗?
答案 0 :(得分:3)
用sync
方法包装async
的方法可以带来一些好处。基础方法仍将是同步的,但是您可以将该方法卸载到另一个线程,因此以前等待的线程现在可以继续执行。因此,在您的示例中,如果UI线程调用了阻塞方法GetHTTPResource
,则可以通过使用异步包装将该方法卸载到另一个线程来实现UI响应能力。我向您推荐此blog post,我认为它可以使您更好地理解async
比sync
的含义。 (this other覆盖sync
上的async
)。
在async
上有sync
时,仍然有一个线程被阻塞。这就是为什么在Web应用程序中几乎没有意义的原因,将异步包装器用于同步功能没有性能优势。引用上述文章(重点是我的):
能够异步调用同步方法没有任何作用 扩展性,因为您通常仍在使用相同的 资源量,如果您同步调用它 (实际上,您的使用量有所增加,因为 安排时间),您只是在使用其他资源 它,例如来自线程池而不是特定线程的线程 您正在执行。吹捧的可扩展性优势 异步实现是通过减少 您使用的资源,需要将其纳入实现中 一种异步方法...这不是通过包装来实现的
例如,在ASP.NET application的情况下,完整的async
代码允许线程在其他请求等待I / O操作完成时处理新请求,从而实现更高的可伸缩性。另一方面,如果代码具有用于I / O操作的基础同步方法,则将阻塞线程,这些线程将无法执行任何操作,只能等到这些操作完成。因此,在Web应用程序中,async
胜过sync
通常没有任何好处。
答案 1 :(得分:-4)
是的,您的同步功能可以变为异步,例如在HTTP Request中,您可以更改同步功能
public static Task<HttpResponseMessage> GetRequest(string requestUri, Dictionary<string, string> requestHeaders)
{
return HttpRequestFactory.Get(requestUri, requestHeaders);
}
呼叫功能
var result = HttpClient.GetRequest(requestUri, _request, _requestHeaders)
您将像这样将其更改为异步
public static async Task<HttpResponseMessage> GetRequest(string requestUri, Dictionary<string, string> requestHeaders)
{
return await HttpRequestFactory.Get(requestUri, requestHeaders);
}
调用功能
var result = HttpClient.GetRequest(requestUri, _request, _requestHeaders).Result;
希望如此对您有帮助。