GetResponseAsync不接受的CancellationToken [英] GetResponseAsync does not accept cancellationToken

查看:273
本文介绍了GetResponseAsync不接受的CancellationToken的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎GetResponseAsync不异步/等待接受的CancellationToken。所以,问题是我怎么可以取消下面的步骤操作,提供了我需要从响应收集饼干:

It seems that GetResponseAsync does not accept cancellationToken in Async/Await. So the question is how can i cancel the bellow procedure, provided i need to collect Cookies from response:

 using (HttpWebResponse response = (HttpWebResponse) await request.GetResponseAsync())
 {
    cookies.Add(response.Cookies);
 }

这是另一种code实现,上面还欢迎。

An alternative code to achieve the above is also welcome.

推荐答案

像这样的东西应该工作(未经测试):

Something like this should work (untested):

public static class Extensions
{
    public static async Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request, CancellationToken ct)
    {
        using (ct.Register(() => request.Abort(), useSynchronizationContext: false))
        {
            var response = await request.GetResponseAsync();
            ct.ThrowIfCancellationRequested();
            return (HttpWebResponse)response;
        }
    }
}

在理论上,如果取消请求对克拉 request.Abort 被调用,等待request.GetResponseAsync()应该抛出一个引发WebException 。 IMO虽然,它总是一个好主意,消耗的结果时,以减轻比赛条件检查明确取消,所以我称之为 ct.ThrowIfCancellationRequested()

In theory, if cancellation is requested on ct and request.Abort is invoked, await request.GetResponseAsync() should throw a WebException. IMO though, it's always a good idea to check for cancellation explicitly when consuming the result, to mitigate race conditions, so I call ct.ThrowIfCancellationRequested().

另外,我认为 request.Abort 是线程安全的(可以从任何线程调用),所以我用 useSynchronizationContext:假(我没有验证)。

Also, I assume that request.Abort is thread-safe (can be called from any thread), so I use useSynchronizationContext: false (I haven't verified that).

【更新】,以解决如何引发WebException 引起的取消和其他错误区分的OP的评论。这是它如何完成,因此 TaskCanceledException (从 OperationCanceledException 导出)将在消除被正确抛出:

[UPDATED] to address the OP's comment on how to differentiate between WebException caused by cancellation and any other error. This is how it can be done, so TaskCanceledException (derived from OperationCanceledException) will be correctly thrown upon cancellation:

public static class Extensions
{
    public static async Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request, CancellationToken ct)
    {
        using (ct.Register(() => request.Abort(), useSynchronizationContext: false))
        {
            try
            {
                var response = await request.GetResponseAsync();
                return (HttpWebResponse)response;
            }
            catch (WebException ex)
            {
                // WebException is thrown when request.Abort() is called,
                // but there may be many other reasons,
                // propagate the WebException to the caller correctly
                if (ct.IsCancellationRequested)
                {
                    // the WebException will be available as Exception.InnerException
                    throw new OperationCanceledException(ex.Message, ex, ct);
                }

                // cancellation hasn't been requested, rethrow the original WebException
                throw;
            }
        }
    }
}

这篇关于GetResponseAsync不接受的CancellationToken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆