且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用CancellationToken进行异步/等待不会取消操作

更新时间:2022-06-09 09:32:52

我想使用CancellationToken中止文件下载

I want to use the CancellationToken to abort a file download

下载文件是一项I/O操作,.NET平台上提供了异步可取消(基于I/O完成端口)功能.但是您似乎并没有使用它们.

Downloading a file is an I/O operation, for which asynchronous cancelable (I/O completion port based) functions are available on the .NET platform. Yet you seem to not be using them.

相反,您似乎正在使用 Task.Run 创建(一系列)任务,这些任务执行阻止I/O,其中取消令牌没有传递给 Task中的每个任务.运行链.

Instead you appear to be creating (a chain of) tasks using Task.Run that perform blocking I/O, where a cancelation token is not passed on to each task in your Task.Run chain.

有关进行异步,可等待和可取消的文件下载的示例,请参阅:

For examples of doing async, awaitable and cancelable file downloads, refer to:

  • Using HttpClient: How to copy HttpContent async and cancelable?
  • Windows Phone: Downloading and saving a file Async in Windows Phone 8
  • Using WebClient: Has its own cancellation mechanism: the CancelAsync method, you can connect it to your cancellation token, using the token's Register method:
myToken.Register(myWebclient.CancelAsync);

  • 使用抽象的WebRequest :如果它不是使用附加的取消令牌创建的,就像您编辑的示例一样,并且您实际上并没有下载文件,而是在阅读内容字符串,则需要结合使用前面提到的几种方法.
  • Using the abstract WebRequest: If it was not created using an attached cancelation token, as seems to be the case for your edited example, and you are not actually downloading a file, but reading a content string, you need to use a combination of a few of the earlier mentioned methods.
  • 您可以执行以下操作:

    static async Task<string> WsGetResponseString(WebRequest webreq, CancellationToken cancelToken)`
    {
        cancelToken.Register(webreq.Abort);
        using (var response = await webReq.GetResponseAsync())
        using (var stream = response.GetResponseStream())
        using (var destStream = new MemoryStream())
        {
            await stream.CopyToAsync(destStream, 4096, cancelToken);
            return Encoding.UTF8.GetString(destStream.ToArray());
        }
    }