GetResponseAsync不接受的CancellationToken [英] GetResponseAsync does not accept 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屋!