在请求取消之前永远不会结束的任务

nel*_*eus 8 .net asynchronous task-parallel-library

我需要一个永远不会结束的任务,直到请求取消.目前最简单的方法是:

var cancellation = new CancellationTokenSource();

var task = Task.Factory.StartNew(async () =>
{
    while (true)
    {
        await Task.Delay(10000, cancellation.Token);
    }
}, cancellation.Token).Unwrap();
Run Code Online (Sandbox Code Playgroud)

我不喜欢的是对Task.Delay方法的调用,因为它需要有限的等待时间间隔.

有更优雅的解决方案吗?

Lee*_*Lee 9

您应该能够订阅令牌的取消并完成任务,然后:

public static Task UntilCancelled(CancellationToken tok)
{
    var tcs = new TaskCompletionSource<object>();
    IDisposable subscription = null;
    subscription = tok.Register(() =>
    {
        tcs.SetResult(null);
        subscription.Dispose();
    });

    return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)


nos*_*tio 7

作为替代TaskCompletionSourcetoken.Register,这里有一些俏皮话:

var task = new Task(() => {}, token); // don't do task.Run()!
Run Code Online (Sandbox Code Playgroud)

或者,简单地说:

var task = Task.Delay(Timeout.Infinite, token);
Run Code Online (Sandbox Code Playgroud)

Timeout.Infinite当前的Task.Delay实现中甚至还有一个很好的优化.

  • 最后一种情况我觉得最简单所以最优雅,看起来很棒.我忘记了这个"神奇"常量`Timeout.Infinite`,幸运的是这个方法接受了它. (3认同)