异步webresponse任务上的状态代码

时间:2012-10-16 15:12:02

标签: c# .net-4.0 exception-handling task-parallel-library

我想尽可能快地点击(100k +)过多的JSON文件,序列化它们,并存储请求的HTTP响应状态代码(无论是成功还是失败)。 (我使用System.Runtime.Serialization.JsonDataContract)。我打算继续使用状态代码和序列化对象,但作为测试床我有这段代码:

List<int> ids = new List<int>();
for (int i = MIN; i < MAX; i++)
    ids.Add(i);
var tasks = ids.Select(id =>
{
var request = WebRequest.Create(GetURL(id));
return Task
    .Factory
    .FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, id)
    .ContinueWith(t =>
    {
    HttpStatusCode code = HttpStatusCode.OK;
    Item item = null;
    try
    {
        using (var stream = t.Result.GetResponseStream())
        {
        DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Item));
        item = ((Item)jsonSerializer.ReadObject(stream));
        }
    }
    catch (AggregateException ex)
    {
        if (ex.InnerException is WebException)
        code = ((HttpWebResponse)((WebException)ex.InnerException).Response).StatusCode;
    }

    });
}).ToArray();
Task.WaitAll(tasks);

使用这种方法,我能够比以前的同步方法更快地处理文件。

但是,我知道GetResponseStream()在状态代码为WebException4xx时会引发5xx。因此,要捕获这些状态代码,我需要捕获此异常。但是,在此TPL的上下文中,它嵌套在InnerException的{​​{1}}上。这使得这条线真的很混乱:

AggregateException

尽管如此,这很有用......我想知道在这种情况下是否有更好/更清晰的方法来捕获这样的异常?

2 个答案:

答案 0 :(得分:2)

查看MSDN文章:Exception Handling (Task Parallel Library)

例如,您可能希望按如下方式重写代码:

try
{
    using (var stream = t.Result.GetResponseStream())
    {
        DataContractJsonSerializer jsonSerializer = new
            DataContractJsonSerializer(typeof(Item));

        item = ((Item)jsonSerializer.ReadObject(stream));
    }
}
catch (AggregateException ex)
{
    foreach (var e in ex.InnerExceptions)
    {
        bool isHandled = false;
        if (e is WebException)
        {
            WebException webException = (WebException)e;
            HttpWebResponse response = webException.Response as HttpWebResponse;
            if (response != null)
            {
                code = response.StatusCode;
                isHandled = true;
            }
        }

        if (!isHandled)
            throw;
    }
}

答案 1 :(得分:1)

尝试使用此尺寸。 GetBaseException返回导致问题的异常。

try
{
}
catch (System.AggregateException aex)
{

    var baseEx = aex.GetBaseException() as WebException;
    if (baseEx != null)
    {
        var httpWebResp = baseEx.Response as HttpWebResponse;
        if (httpWebResp != null)
        {
            var code = httpWebResp.StatusCode;
            // Handle it...
        }                    
    }

    throw;
}