5

我有一个要取消的任务。

执行此操作的常规方法是使用CancellationToken.

this.task = new SpecialTask(() =>
{
    for (int i = 0; i < ushort.MaxValue; i++)
    {
        CancelToken.ThrowIfCancellationRequested();
        Console.WriteLine(i);
    }
}, this.CancelToken);

然而,在现实世界中,事情从来没有那么简单。我们的异步代码不能循环,它看起来像这样:

this.task = new SpecialTask(() =>
{
    CancelToken.ThrowIfCancellationRequested();
    Operation1();

    CancelToken.ThrowIfCancellationRequested();
    Operation267(CancelToken);

    CancelToken.ThrowIfCancellationRequested();
    object232.Operation345();

    CancelToken.ThrowIfCancellationRequested();
    object99.Operation44(CancelToken);

    CancelToken.ThrowIfCancellationRequested();
    Operation5(CancelToken);

    ...

    CancelToken.ThrowIfCancellationRequested();
    Operation...n(CancelToken);

}, this.CancelToken);

我对对象和方法名称使用了随机数来表明不能创建任何循环。

最困扰的是我必须CancelToken.ThrowIfCancellationRequested()一遍又一遍地写同样的东西。

而且,好像这还不够,我必须CancellationToken在我的代码中拖动所有内容,以便能够在正确的时间停止长时间运行的操作 - 根据微软的说法。

话虽如此,有没有办法可以免除这些毒害我的代码的重复调用?

我们也知道,当使用

try
{
    task.Wait(cancelToken);
}
catch(OperationCancelledException)
{
}

anOperationCancelledException被抛出并捕获该Wait方法。CancelToken.ThrowIfCancellationRequested()但是,如果时不时没有检查,任务执行的长时间操作不会停止。

当异常被捕获等待时,有什么办法可以使内部操作停止?

4

1 回答 1

2

您可以将代码重构为循环,以避免每行之间的重复取消:

var actions = new List<Action>()
{
    ()=>Operation1(),
    ()=>Operation267(CancelToken),
    ()=>object232.Operation345(),
    //...
};

foreach (var action in actions)
{
    action();
    CancelToken.ThrowIfCancellationRequested();
}
于 2013-06-28T15:24:41.900 回答