设置HttpClient的一个太短的超时崩溃过程 [英] Setting HttpClient to a too short timeout crashes process

查看:2866
本文介绍了设置HttpClient的一个太短的超时崩溃过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,当我使用 System.Net.HttpClient 带短超时,有时可能崩溃的过程中,即使当它被包裹在一个try-catch块。这里有一个简短的程序来重现此。

I've noticed that when I'm using System.Net.HttpClient with a short timeout, it may sometimes crash the process, even when it is wrapped in a try-catch block. Here's a short program to reproduce this.

public static void Main(string[] args)
{
    var tasks = new List<Task>();
    for (int i = 0; i < 1000; i++)
    {
        tasks.Add(MakeHttpClientRequest());
    }
    Task.WaitAll(tasks.ToArray());

}

private async static Task MakeHttpClientRequest()
{            
    var httpClient = new HttpClient { Timeout = TimeSpan.FromMilliseconds(1) };
    var request = "whatever";
    try
    {
        HttpResponseMessage result =
            await httpClient.PostAsync("http://www.flickr.com/services/rest/?method=flickr.test.echo&format=json&api_key=766c0ac7802d55314fa980727f747710",
                                 new StringContent(request));             
        await result.Content.ReadAsStringAsync();                
    }
    catch (Exception x)
    {
        Console.WriteLine("Error occurred but it is swallowed: " + x);
    }
}

运行,这将崩溃的过程中有以下情况除外:

Running this will crash the process with the following exception:

Unhandled Exception: System.AggregateException: One or more errors occurred. ---> System.Net.WebException: The request was canceled
   at System.Net.ServicePointManager.FindServicePoint(Uri address, IWebProxy proxy, ProxyChain& chain, HttpAbortDelegate& abortDelegate, Int32& abortState)
   at System.Net.HttpWebRequest.FindServicePoint(Boolean forceFind)
   at System.Net.HttpWebRequest.get_ServicePoint()
   at System.Net.AuthenticationState.PrepareState(HttpWebRequest httpWebRequest)
   at System.Net.AuthenticationState.ClearSession(HttpWebRequest httpWebRequest)
   at System.Net.HttpWebRequest.ClearAuthenticatedConnectionResources()
   at System.Net.HttpWebRequest.Abort(Exception exception, Int32 abortState)
   at System.Net.HttpWebRequest.Abort()
   at System.Net.Http.HttpClientHandler.OnCancel(Object state)
   at System.Threading.CancellationCallbackInfo.ExecutionContextCallback(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.CancellationCallbackInfo.ExecuteCallback()
   at System.Threading.CancellationTokenSource.CancellationCallbackCoreWork(CancellationCallbackCoreWorkArguments args)
   at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
   --- End of inner exception stack trace ---
   at System.Threading.CancellationTokenSource.ExecuteCallbackHandlers(Boolean throwOnFirstException)
   at System.Threading.CancellationTokenSource.NotifyCancellation(Boolean throwOnFirstException)
   at System.Threading.CancellationTokenSource.TimerCallbackLogic(Object obj)
   at System.Threading.TimerQueueTimer.CallCallbackInContext(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.TimerQueueTimer.CallCallback()
   at System.Threading.TimerQueueTimer.Fire()
   at System.Threading.TimerQueue.FireNextTimers()
   at System.Threading.TimerQueue.AppDomainTimerCallback()

在一个小挖,似乎当的HttpClient 中止有关<$ C $之前的要求C>的ServicePoint 创建,的HttpWebRequest 尝试,通过<$ C创建的ServicePoint $ C> ServicePointManager.FindServicePoint ,它抛出一个RequestCanceled。由于这种异常在试图取消该请求的线程抛出,这是没有被捕获,并且进程死掉。

Digging in a little, it seems that when HttpClient aborts the request before a relevant ServicePoint is created, HttpWebRequest attempts to create the ServicePoint, via ServicePointManager.FindServicePoint, which throws a RequestCanceled. Since this exception is thrown in the thread that attempts to cancel the request, it is not caught, and the process dies.

我缺少的东西吗?你有没有遇到这个问题?

Am I missing something? Have you run into this issue?

推荐答案

HttpWebRequest.Abort()是在后台抛出异常/定时器线程。这有没有关系的HttpClient的任务管理。

HttpWebRequest.Abort() is throwing an exception on a background/timer thread. This has nothing to do with HttpClient's Task management.

HttpWebRequest.Abort除外()应固定在.NET 4.5 GDR1。
http://support.microsoft.com/kb/2750149
http://support.microsoft.com/kb/2750147

The exception from HttpWebRequest.Abort() should be fixed in .NET 4.5 GDR1. http://support.microsoft.com/kb/2750149 http://support.microsoft.com/kb/2750147

这篇关于设置HttpClient的一个太短的超时崩溃过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆