如何创建取消的任务

问题描述 投票:8回答:2

我正在写一个Stream类,在ReadAsync方法中受阻。请大家看一下代码,我想用我的英文可以更好的解释这个情况。

public override Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken)
{
    if (!cancellationToken.IsCancellationRequested)
    {
        return _connection.ReceiveAsync(new ArraySegment<byte>(buffer, offset, count));
    }
    return // <---------------    what here?
}

使用ILSpy我可以看到,其他Stream类返回一个取消的任务,如下图。

return new Task<TResult>(true, default(TResult), TaskCreationOptions.None, cancellationToken); 

但是那个Task的构造函数是内部的,我无法调用它。

Google根本没帮到我。

task-parallel-library async-await c#-5.0 cancellation-token
2个回答
14
投票

我所知道的最直接的方法是用一个 TaskCompletionSource:

var tcs = new TaskCompletionSource<int>();
tcs.TrySetCanceled();
return tcs.Task;

如果你以前没有使用过它。TaskCompletionSource 提供了一个 "承诺式 "的任务,基本上可以让你说:"给你,拿着这个。Task 现在,只要我准备好了,我就会提供结果(或报告错误取消)。" 当你想自己安排coordinate工作的时候,它是很有用的,而不是简单地依赖一个? TaskScheduler.

或者,如果你用 async/await你可以强制取消异常自动传播到结果中去。Task:

public async override Task<int> ReadAsync(
    byte[] buffer,
    int offset,
    int count,
    CancellationToken cancellationToken)
{
    cancellationToken.ThrowIfCancellationRequested();

    return await _connection.ReceiveAsync(
        new ArraySegment<byte>(
            buffer,
            offset,
            count));
}

10
投票

负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 负责人: 下一个版本的.Net(v4.5.3),增加了利用内部构造函数创建取消任务的方法。 增加了一种利用内部构造函数来创建取消任务的方法。有通用和非通用两个版本。

var token = new CancellationToken(true);
Task task = Task.FromCanceled(token);
Task<int> genericTask = Task.FromCanceled<int>(token);

请记住 CancellationToken 呼叫前必须取消正在使用的 FromCanceled

© www.soinside.com 2019 - 2024. All rights reserved.