继续使用返回任务的方法

时间:2014-09-30 12:40:40

标签: c# task-parallel-library

我想执行三个步骤。一个准备任务,一个工作任务封装在返回任务的方法和一个需要上一步结果的清理任务中。但是我不确定我是否以正确的方式解开并访问'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...");
}

2 个答案:

答案 0 :(得分:1)

您可以使用异步方法执行所有步骤并返回任务:

static async Task DoAsync()
{
    Console.WriteLine("Prepare");
    Console.WriteLine(await WorkAsync());
}

static void Main(string[] args)
{
    DoAsync().Wait();
    Console.ReadLine();
}

答案 1 :(得分:0)

如果使用Rackspace Threading Library,则可以轻松确保使用所需的语义执行操作。此外,它以可预测的方式处理已取消和出现故障的任务(至少可以说,当您不使用async / await时,这是一项艰巨的任务)。

  • 使用Select表示不返回Task(值或void
  • 的续集
  • 使用Then表示返回TaskTask<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();
}