阻止任务继续
本文关键字:继续 任务 | 更新日期: 2023-09-27 18:36:37
我正在使用任务延续在WinForm项目上进行长时间运行的操作。
var task1 = Task.Factory.StartNew(() => DoSomeWork());
var task2 = task1.ContinueWith(result => DoSomeMoreWork(), TaskContinuationOptions.OnlyOnRanToCompletion);
var task3 = task2.ContinueWith(result => DoFinalWork(), TaskContinuationOptions.OnlyOnRanToCompletion);
只有在任务 2 上执行的 DoSomeMoreWork() 函数满足某些条件时,我只想继续执行任务 3。如何做到这一点?
来自MSDN
用户定义的值可以从前置值传递到其 继续,以便输出 前因可以作为延续的输入
因此,一种方法是在task3中,在执行任何工作之前检查任务2的结果。
var task2 = task1.ContinueWith(result => DoSomeMoreWOrk(), TaskContinuationOptions.OnlyOnRanToCompletion);
var task3 = task2.ContinueWith(x => DoFinalWork(x.Result));
从任务 2 返回的结果的位置决定了任务 3 中发生的情况。
编辑另一种解决方案是在操作中不满足某些条件时取消任务 2。然后甚至没有计划继续任务。
来自 MSDN
防止延续在其前因是 已取消,请在创建 延续。
所以任务3的定义变成了
var task3 = task2.ContinueWith(result => DoFinalWork(), TaskContinuationOptions.NotOnCancelled);
另一种选择是将 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);
如果您可以使用异步 CTP 或 .NET 4.5(我认为两者都有上线许可证),您可以将延续替换为 async/await 以获得更干净的代码。
如果将工作线程函数转换为使用异步,则代码几乎与同步版本一样清晰:
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());
}
}