取消C# HttpClient的GetStreamAsync调用

9

我需要在一个旧的C#项目中添加取消HTTP请求的可能性。

该项目使用HttpClient::GetStreamAsync,似乎不支持Cancellation tokens。

GetStreamAsync调用可以取消吗? 我还有什么其他选择?

3个回答

7
2022更新: 我保留了MSDN文章的链接,因为在我写这篇文章时,链接仍然有效。但是,这个链接已经有些年头了,可能最终会失效。此外,根据下面回答的评论,我轻微编辑了我的回答内容,删除了一个无用的句子和一个毫无意义的斜体词。

原始回答: 我在2012年的一个MSDN博客文章中发现了一种替代方案。这可能对你有所帮助。作者使用了 GetStringAsync,但是原理也适用于 GetStreamAsync。文章链接: Await HttpClient.GetStringAsync() and cancellation.

在该MSDN文章中,作者使用了 GetAsync(...),可以接受取消参数。Nathan的问题的一个简单解决方案可能是这样的...

CancellationTokenSource cancellationSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationSource.Token;

Uri uri = new Uri("some valid web address"); 
HttpClient client = new HttpClient();
await client.GetAsync(uri, cancellationToken);

// In another thread, you can request a cancellation.
cancellationSource.Cancel();

请注意,取消操作是在 CancellationTokenSource 对象上进行的,而不是 CancellationToken 对象。

3
如果您引用文章中相关的部分(根据文章的许可),这个回答会更好。如果没有文章的细节,如果链接失效,这个回答将不再提供答案。 - psubsee2003
2
你在例子中漏掉了使用GetStreamAsync或GetStringAsync的部分,这使它变得无用。而你所说的“由于流的工作方式”是什么意思? - SerG

6

这是一个简单的例子。

public async Task<Stream> GetWebData(string url, CancellationToken? c = null)
{
    using (var httpClient = new HttpClient())
    {
        var t = httpClient.GetAsync(new Uri(url), c ?? CancellationToken.None);
        var r = await t;
        return await r.Content.ReadAsStreamAsync();
    }
}

0

和John的答案一样,只是作为扩展方法:

 internal static class HttpClientExtensions
    {
        public async static Task<Stream> GetStreamAsync(this HttpClient httpClient, string url, CancellationToken ct)
        {
            var response = await httpClient.GetAsync(new Uri(url), ct);
            return await response.Content.ReadAsStreamAsync();
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接