Tôi nhận thấy rằng khi tôi đang sử dụng System.Net.HttpClient
với thời gian chờ ngắn, đôi khi có thể làm hỏng quy trình, ngay cả khi nó được bao bọc trong khối thử. Đây là một chương trình ngắn để tái tạo điều này.Đặt HttpClient thành quá trình treo thời gian chờ quá ngắn
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);
}
}
Chạy này sẽ sụp đổ quá trình với các ngoại lệ sau đây:
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()
Đào trong một chút, có vẻ như rằng khi HttpClient
hủy bỏ yêu cầu trước khi có liên quan ServicePoint
được tạo ra, HttpWebRequest
nỗ lực để tạo ra các ServicePoint
, thông qua ServicePointManager.FindServicePoint
, trong đó ném một RequestCanceled. Vì ngoại lệ này được ném vào chuỗi cố gắng hủy bỏ yêu cầu, nó không bị bắt và quá trình này sẽ chết.
Tôi có thiếu gì đó không? Bạn đã gặp phải vấn đề này chưa?
Đây là một lỗi tuyệt vời. a) Bạn có thể thử thêm một lượt thử quanh toàn bộ Main không? b) Bạn có thể móc sự kiện EventScheduler.UnobservedTaskException Event không? – usr
@usr: đã thử cả hai và như mong đợi nó không giúp ích gì. Try-catch trên main chỉ nắm bắt được công cụ chủ đề chính và ngoại lệ xử lý sự cố không phải là một UnobservedTaskException. –
Bạn không thể nắm bắt được tổng hợp ngoại lệ? Và đối phó với nó từ đó? bắt (AggregateException ae) { } – PaulG