【问题标题】:status code on async webresponse task异步 webresponse 任务的状态码
【发布时间】:2012-10-16 23:51:53
【问题描述】:

我想尽快访问大量 (100k+) 的 JSON 文件,将它们序列化,并存储请求的 HTTP 响应状态代码(无论是成功还是失败)。 (我正在使用System.Runtime.Serialization.JsonDataContract)。我打算对状态码和序列化对象做进一步的工作,但作为一个测试平台,我有这个 sn-p 代码:

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);

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

不过,我知道当状态码为 4xx5xx 时,GetResponseStream() 会抛出 WebException。因此,要捕获这些状态代码,我需要捕获此异常。但是,在此 TPL 的上下文中,它嵌套在 InnerException 上的 AggregateException 中。这让这一行真的很混乱:

    code = ((HttpWebResponse)((WebException)ex.InnerException).Response).StatusCode;

虽然,这行得通...我想知道在这种情况下是否有更好/更清晰的方法来捕获此类异常?

【问题讨论】:

  • 既然你用 .net-4.0 标记它,我猜 4.5 中的 HttpClient 类不是一个选项。你用的是VS2012吗?如果是这样,您可以使用异步目标包和目标 4.0。
  • 不,我正在使用 VS2010 自动取款机。我同意 '12 和 4.5 现在有一些更好的东西来处理这种事情。
  • 没有过多研究,但是你可能会使用 WebClient 和 EAP 获得更简单/更简单的代码,因为你可以只检查生成的事件参数是否有错误/取消

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


【解决方案1】:

看看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;
    }
}

【讨论】:

    【解决方案2】:

    试穿它的大小。 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;
    }
    

    【讨论】:

    • 这是不正确的,因为 AggregateException.GetBaseException() 总是返回 AggregateException 或 null。
    • 嗯,你是对的。这就是我没有运行我的代码所得到的。今天晚些时候我会检查一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多