C# 异步比同步长15倍
我正在比较从我的方法中去掉C# 异步比同步长15倍,c#,asp.net,asp.net-web-api,async-await,dotnet-httpclient,C#,Asp.net,Asp.net Web Api,Async Await,Dotnet Httpclient,我正在比较从我的方法中去掉wait关键字时的性能,它使我的性能提高了15倍以上 以下方法的性能要好得多: private static async Task<HttpResponseMessage> AwaitResponse(HttpRequest proxy) { foreach (var header in proxy.Request.Headers) { Client.Instance.DefaultRequestHeaders.Add(hea
wait
关键字时的性能,它使我的性能提高了15倍以上
以下方法的性能要好得多:
private static async Task<HttpResponseMessage> AwaitResponse(HttpRequest proxy)
{
foreach (var header in proxy.Request.Headers)
{
Client.Instance.DefaultRequestHeaders.Add(header.Key, header.Value);
}
var response = Client.Instance.SendAsync(proxy.Request).Result;
return response;
}
private静态异步任务等待响应(HttpRequest代理)
{
foreach(proxy.Request.Headers中的var头)
{
Client.Instance.DefaultRequestHeaders.Add(header.Key,header.Value);
}
var response=Client.Instance.sendaync(proxy.Request).Result;
返回响应;
}
比这一个:
private static async Task<HttpResponseMessage> AwaitResponse(HttpRequest proxy)
{
foreach (var header in proxy.Request.Headers)
{
Client.Instance.DefaultRequestHeaders.Add(header.Key, header.Value);
}
var response = Client.Instance.SendAsync(proxy.Request);
return await response;
}
private静态异步任务等待响应(HttpRequest代理)
{
foreach(proxy.Request.Headers中的var头)
{
Client.Instance.DefaultRequestHeaders.Add(header.Key,header.Value);
}
var response=Client.Instance.sendsync(proxy.Request);
返回等待响应;
}
注意我在方法的第一个版本中调用.Result的方式
为什么会发生这种情况?为什么会有如此巨大的性能损失?
请注意,
Client
只是HttpClient
的一个静态实例 使用wait
时,代码的执行上下文将挂起,直到异步方法返回。默认情况下,await
尝试将新线程恢复到其起源的传入同步上下文。这有时会影响性能,因为CLR需要等待原始SynchronizationContext封送回来
一般来说,除非您有特定的需要返回到您离开的同一线程上下文(例如,在客户端应用程序中,返回到UI线程),否则最好添加
ConfigureAwait(false)
并在任意线程上继续。如果您实际上没有对代码段中的任何内容使用响应,则无需实际使用async/wait或调用。Result
。您只需返回任务
,让调用者等待或在更高级别调用.Result
private static Task<HttpResponseMessage> AwaitResponse(HttpRequest proxy) {
foreach (var header in proxy.Request.Headers) {
Client.Instance.DefaultRequestHeaders.Add(header.Key, header.Value);
}
return Client.Instance.SendAsync(proxy.Request);
}
私有静态任务等待响应(HttpRequest代理){
foreach(proxy.Request.Headers中的var头){
Client.Instance.DefaultRequestHeaders.Add(header.Key,header.Value);
}
返回Client.Instance.sendaync(proxy.Request);
}
我还建议进行审查
斯蒂芬·克利里
关于不混合阻塞和异步代码的问题,以及关于如何以及何时配置等待(false)何时可以1。您说“x15增加”,但没有指定数字。这是10毫秒对150毫秒,还是200毫秒对3000毫秒?这很重要。2.是否有许多其他并发请求同时执行类似的操作
await
放弃线程,并将上下文封送回返回时的位置。如果有许多请求,您的线程池可能正忙。3.将ConfigureAwait(false)
添加到您的await
是否会改变行为?它会从1000毫秒变为12000毫秒。没有其他并发请求ConfigureAwait(false)解决了它!!!!!!!!!!!!!!!!这是一个很好的观点,因此您会说“如果在我的应用程序中不使用async/await,那么使用async/await的目的是什么?而是让客户端这样做?”??不,关键字async/await只需要它,您需要保留上下文以便进一步处理。例如,如果在调用SendAsync
后需要在方法中对结果执行某些操作,则async/await
将得到保证。但是,在这种情况下您不需要它,因此在这种方法中不需要使用async/await
。虽然您可以省略async/await,只需从自己的异步函数返回内部任务,但它并不总是最佳选择。这是斯蒂芬·克利里,又一次,在电视上。简言之,如果出现异常,直接返回内部任务会使您的函数不会显示在堆栈跟踪中。