我有一些关于LINQ查询的GUI。查询需要一些时间来执行,所以我希望GUI能够响应并显示繁忙的指示器和进度条。许多查询都是为了检查数据中存在的某些条件。如果查询返回空结果,则应用程序将继续进行下一个查询。如果返回结果,则返回集将具有严重的“警告”或“错误”。如果是警告,则将继续执行。如果它是错误,它将停止。
许多代码与线程池和GUI一起玩“乒乓”。准代码:
TaskFactory.StartNew(()=>
{
Run in background
}.ContinueInGui(()=>
{
Update something
}).ContinueInBackground(()=>
{
Do more work;
}).ContinueInGui(()=> etc etc这是整洁又漂亮的。但是,如果在数据中发现错误,我不知道如何插入条件以进行不同的继续路由或中断延续链。
没有用于ContinueWithIf( 谓词,委托{},TaskScheduler)的方法,我是否使用TaskCancellation,是否抛出异常?还是有一些我没有想到的简单的分支机制?
发布于 2011-10-25 17:28:20
这里的一个很好的选择是使用一个CancelationTokenSource,如果您想要“破坏”您的延续链,只需标记它被取消。通过将TaskContinuationOptions.NotOnCanceled包含在后续任务的ContinueWith中,您可以通过将CancelationTokenSource标记为已取消,从而使它们在任何时候都不会被调度。
如果您确实希望使用谓词,而不是在main方法中设置延续,则需要创建一个自定义方法来为您处理这个问题。这可以通过一个附加延拓的扩展方法来完成--这个延拓可以检查谓词,并在适当的情况下触发延续。这看起来应该是:
public static Task ContinueWithIf(this Task task, Func<bool> predicate, Action<Task> continuation, TaskScheduler scheduler)
{
var tcs = new TaskCompletionSource<object>();
task.ContinueWith( t =>
{
if (predicate())
{
new TaskFactory(scheduler).StartNew(
() =>
{
continuation(task);
tcs.SetResult(null);
});
}
else
{
tcs.TrySetCanceled();
}
});
return tcs.Task;
}当然,您可能还想为Task<T>制作一个版本,并处理任务中的故障/取消状态。话虽如此,它应该能正常运作。
发布于 2011-10-24 08:21:38
如果存在错误,则应考虑相应地使任务出错。然后您可以在TaskContinuationOptions.OnlyOnRanToCompletion调用中使用ContinueWith等。
在任务生命结束时,基本上有三种可能的状态:
您可以使ContinueWith应用于这些状态的任何合理组合,如果您想要根据错误、成功和取消等执行不同的事情,则可以将不同的延续附加到同一个父任务。
https://stackoverflow.com/questions/7872860
复制相似问题