我想执行三个步骤的工作。一个准备任务、一个封装在返回任务的方法中的工作任务和一个需要上一步结果的清理任务。但我不确定我是否以正确的方式展开和访问“result”属性,或者是否有更干净的版本将该方法包含在执行链中。
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine("Prepare"))
.ContinueWith(x => Work())
.ContinueWith(x => Console.WriteLine(x.Unwrap().Result));
Console.ReadLine();
}
private static Task<string> Work()
{
Thread.Sleep(1500);
return Task.Factory.StartNew(() => "See my results...");
}
最佳答案
如果使用Rackspace Threading Library,则很容易确保使用所需的语义执行操作。此外,它以可预测的方式处理取消的和出现故障的任务(至少可以说,这是一项令人畏惧的壮举,因为您没有使用async
/await
)。
对于不返回Select
的连续操作,请使用Task
(值或void
)
对于返回aThen
或Task
的连续操作,请使用Task<T>
。
例子:
static void Main(string[] args)
{
Task operation = Task.Factory.StartNew(() => Console.WriteLine("Prepare"))
.Then(_ => WorkAsync())
.Select(resultTask => Console.WriteLine(resultTask.Result));
operation.Wait();
Console.ReadLine();
}
private static Task<string> WorkAsync()
{
return DelayedTask.Delay(TimeSpan.FromMilliseconds(1500))
.Select(_ => "See my results...");
}
如果您仍然想直接使用tpl,那么原始代码的主要问题(除了取消和异常处理)是调用
Unwrap
的位置。实际上,您希望将其放置在以下代码中:// NOTE: I WOULD NOT USE THIS CODE
// (preferring the Threading Library or async/await instead)
static void Main(string[] args)
{
Task.Factory.StartNew(() => Console.WriteLine("Prepare"))
.ContinueWith(x => Work()).Unwrap()
.ContinueWith(x => Console.WriteLine(x.Result));
Console.ReadLine();
}