C#httpClient(阻止异步调用)死锁
作者:互联网
现在的情况
有一个客户端通过HttpClient.GetAsync执行get请求.不幸的是,由于某种原因,我们需要阻止该调用.
为此,使用此Asynchelper类以避免上下文切换死锁(而不是仅使用.Result).
public static class AsyncHelper
{
private static readonly TaskFactory _myTaskFactory = new
TaskFactory(CancellationToken.None,
TaskCreationOptions.None,
TaskContinuationOptions.None,
TaskScheduler.Default);
public static void RunSync(Func<Task> func)
{
AsyncHelper._myTaskFactory
.StartNew<Task>(func)
.Unwrap()
.GetAwaiter()
.GetResult();
}
}
然后,实际的调用如下所示:
AsyncHelper.RunSync(Async Function() Await _httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead))
问题
在使用Netlimiter降低网络速度的压力测试期间,我们遇到了请求未完成的问题.
例如,当我终止网络连接(在NetLimiter中)时,这样的请求将永远保留在客户端.
它将一直留在AsyncHelper.RunSync调用中,直到它运行到httpClient.Timeout中为止.
当连接断开时,是否应该有一个异常终止此调用?我想念什么吗?
解决方法:
事实是,HTTP连接通常位于TCP连接之上.因此,当您强制终止TCP连接而无法发送其“我在这里完成”(或FIN)数据包时,连接的另一端仍然乐于等待更多数据,至少直到某个定义的超时为止可以在套接字查询操作中从上方进行配置.
一种解决方法是在套接字上设置TCP Keep-Alive.请注意,这与HTTP Keep-Alive非常不同.似乎已经发生的另一种选择是使用足够的超时时间.
标签:contextswitchdeadlock,async-await,dotnet-httpclient,c 来源: https://codeday.me/bug/20191119/2033591.html