Ich habe festgestellt, dass wenn ich System.Net.HttpClient
mit einem kurzen Timeout verwenden, kann es manchmal den Prozess abstürzen, auch wenn es in einem try-catch-Block verpackt ist. Hier ist ein kurzes Programm, um dies zu reproduzieren.Einstellung von HttpClient auf einen zu kurzen Timeout stürzt Prozess
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);
}
}
das Lauf wird der Prozess mit folgender Ausnahme abstürzen:
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()
in einem kleinen Graben, so scheint es, dass, wenn HttpClient
die Anforderung bricht ab, bevor ein relevantes ServicePoint
erstellt wird, HttpWebRequest
versucht das zu schaffen ServicePoint
, über ServicePointManager.FindServicePoint
, die eine RequestCanceled wirft. Da diese Ausnahme in dem Thread ausgelöst wird, der versucht, die Anforderung abzubrechen, wird sie nicht abgefangen und der Prozess wird beendet.
Fehle ich etwas? Bist du auf dieses Problem gestoßen?
Dies ist ein erstaunlicher Fehler. a) Können Sie versuchen, einen Try-Catch um den gesamten Main hinzuzufügen? b) Können Sie das Ereignis TaskScheduler.UnobservedTaskException Event haken? – usr
@usr: versuchte beide, und wie erwartet hat es nicht geholfen. Try-catch on main fängt nur Hauptthreads ab, und die prozessauslösende Ausnahme ist keine UnobservedTaskException. –
Konnten Sie die aggregateException nicht abfangen? Und damit von dort umgehen? catch (Aggregate ae) { } – PaulG