简体   繁体   English

从任务中的异步HttpWebRequest调用捕获异常

[英]Catching exceptions from Asynchronous HttpWebRequest Calls in a Task

How would i catch the exception in this method below? 我如何在下面的方法中捕获异常?

    private static Task<string> MakeAsyncRequest(string url)
    {
        if (!url.Contains("http"))
            url = "http://" + url;

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
        request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        request.Method = "GET";
        request.KeepAlive = false;
        request.ProtocolVersion = HttpVersion.Version10;

        Task<WebResponse> task = Task.Factory.FromAsync(
        request.BeginGetResponse,
        asyncResult => request.EndGetResponse(asyncResult),
        (object)null);

        return task.ContinueWith(t => FinishWebRequest(t.Result));

    }

The specific place i am getting 404, 403, etc errors is: 我得到404,403等错误的具体地点是:

Task<WebResponse> task = Task.Factory.FromAsync(
            request.BeginGetResponse,
            asyncResult => request.EndGetResponse(asyncResult),
            (object)null);

I cant figure out how to handle them 我无法弄清楚如何处理它们

Your error is probably happening in your delegate calling request.EndGetResponse(asyncResult) . 您的错误可能发生在您的委托调用request.EndGetResponse(asyncResult)

However you can create the task using: 但是您可以使用以下命令创建任务:

Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);

which should propagate any exceptions to the task. 这应该传播任务的任何例外。

You can check for errors in your ContinueWith delegate: 您可以在ContinueWith委托中检查错误:

return task.ContinueWith(t =>
{
    if (t.IsFaulted)
    {
        //handle error
        Exception firstException = t.Exception.InnerExceptions.First();
    }
    else
    {
        return FinishWebRequest(t.Result);
    }
});

Alternatively if you're using C#5 then you can use async/await to create your MakeAsyncRequest . 或者,如果您使用的是C#5,则可以使用async / await创建MakeAsyncRequest This will unwrap the exception from the AggregateException for you: 这将为您从AggregateException解除异常:

private static async Task<string> MakeAsyncRequest(string url)
{
    if (!url.Contains("http"))
        url = "http://" + url;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
    request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    request.Method = "GET";
    request.KeepAlive = false;
    request.ProtocolVersion = HttpVersion.Version10;

    Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
    WebResponse response = await task;
    return FinishWebRequest(response);
}

So your task changes its state to Faulted state and you can check this error in several ways: 因此,您的任务将其状态更改为Faulted状态,您可以通过以下几种方式检查此错误:

// Inside method MakeAsyncRequest
Task<WebResponse> task = Task.Factory.FromAsync(
    request.BeginGetResponse,
    asyncResult => request.EndGetResponse(asyncResult),
    (object)null);

// this 'task' object may fail and you should check it

return task.ContinueWith(
   t => 
     {
        if (t.Exception != null)
          FinishWebRequest(t.Result))

        // Not the best way to fault "continuation" task
        // but you can wrap this into your special exception
        // and add original exception as a inner exception
        throw t.Exception.InnerException;

        // throw CustomException("The request failed!", t.Exception.InnerException);
     };

In any case you should prepare that any task can fail, so you should use the same technique to handle resulting tasks as well: 在任何情况下,您应该准备任何任务都可能失败,因此您应该使用相同的技术来处理结果任务:

// outside method MakeAsyncRequest
var task = MakeAsyncRequest(string url);

task.ContinueWith(t => 
  // check tasks state or use TaskContinuationOption
  // handing error condition and result
);

try
{
  task.Wait(); // will throw
  Console.WriteLine(task.Result); // will throw as well
}
catch(AggregateException ae)
{
  // Note you should catch AggregateException instead of
  // original excpetion
  Console.WriteLine(ae.InnerException);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM