防止任务继续

时间:2012-06-08 09:34:13

标签: c# task-parallel-library

我在WinForm项目上使用Task continuation进行长时间运行。

var task1 = Task.Factory.StartNew(() => DoSomeWork());

var task2 = task1.ContinueWith(result => DoSomeMoreWork(), TaskContinuationOptions.OnlyOnRanToCompletion);

var task3 = task2.ContinueWith(result => DoFinalWork(), TaskContinuationOptions.OnlyOnRanToCompletion);

如果在task2上执行的DoSomeMoreWork()函数满足某些条件,我只想继续执行task3。怎么办呢?

2 个答案:

答案 0 :(得分:1)

来自MSDN

  

用户定义的值可以从先行词传递给它   在Result属性中继续,以便输出   前提可以作为继续的输入

所以一种方法是在task3中,在做任何工作之前检查来自task2的Result。

var task2 = task1.ContinueWith(result => DoSomeMoreWOrk(), TaskContinuationOptions.OnlyOnRanToCompletion);
var task3 = task2.ContinueWith(x => DoFinalWork(x.Result));

从task2返回的结果确定task3中发生的情况。

修改 的 另一种解决方案是在操作中不满足某些条件时取消task2。然后甚至没有安排继续任务。

来自MSDN

  

如果其前提是阻止继续执行   取消,在创建时指定NotOnCanceled选项   延续。

所以task3定义变为

var task3 = task2.ContinueWith(result => DoFinalWork(), TaskContinuationOptions.NotOnCancelled);

答案 1 :(得分:1)

另一种选择是将task2和task3转换为嵌套任务,只有在满足条件时才执行它们。

假设DoSomeMoreWork返回true来执行此操作,您可以编写类似这样的内容

        var task1 = Task.Factory.StartNew(DoSomeWork);
        var task2 = task1.ContinueWith(result =>
            {
                if (DoSomeMoreWork())
                {
                    Task.Factory.StartNew(DoFinalWork, TaskCreationOptions.AttachedToParent);
                }
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

如果您可以使用Async CTP或.NET 4.5(我认为两者都有Go Live许可证),您可以使用async / await替换continuation以获得更清晰的代码。

如果将worker函数转换为使用async,则代码几乎与同步版本一样清晰:

    private static async void WorkAsync()
    {
        await DoSomeWork();
        if (await DoSomeMoreWork())
        {
            await DoFinalWork();
        }
    }

    private static async Task DoFinalWork()
    {
        Console.WriteLine("Completed");
    }

    private static async Task<bool> DoSomeMoreWork()
    {
        Console.WriteLine("Some More");
        return true;
    }

    private static async Task DoSomeWork()
    {
        Console.WriteLine("Some");
    }

如果您不想从方法中返回任务,可以使用以下代码:

    private static async void WorkAsync()
    {
        await Task.Run(()=>DoSomeWork());
        if (await Task.Run(()=>DoSomeMoreWork()))
        {
            await Task.Run(()=>DoFinalWork());
        }
    }