立即在ContinueWith块内部构建一个调用的任务?

时间:2014-12-15 22:32:30

标签: c# .net task

首先,为标题道歉;我无法想到如何简明扼要地表达我想要做的事情。

我有以下两个功能:

主要代码:

private async Task<PreparationInfo> PrepareRoundtrip()
{
    PreparationInfo output = new PreparationInfo();

    Task.Delay(3000); // stands in for a call to the server to fetch data for how to prepare

    prepare(output) // package result into output

    return output;
}

private Task ExecuteWithPrepare()
{
    if (!PrepareEnabled) // instance variable
        return stateObject.Execute();
    else
    {
        Task<PreparationInfo> prepareTask = PrepareRoundtrip();
        return tceTask.ContinueWith((prepareTaskInternal) =>
        {
            stateObject.Execute(); // this is the Task that I need to return
        });
    }
}

stateObject.Execute()标题:

internal Task Execute()
{
    ...
}

我正在为stateObject.Execute()方法编写一个包装器,它可以在执行之前预先调用一个准备方法(PrepareRoundtrip())来处理一些参数。

如果未启用准备(PrepareEnabled == false),我可以调用Execute()方向并立即返回它返回的任务。如果准备 ,我需要运行准备方法(这个任务是唯一的,我可以根据需要进行更改),然后运行Execute()

我坚持的部分是:

整个函数需要运行并返回,就像直接调用stateObject.Execute()一样,只需添加PrepareRoundtrip()部分,这意味着两件事:

  1. ExecuteWithPrepare()返回的任务需要代表stateObject.Execute()返回的任务。

  2. ExecuteWithPrepare()需要立即返回(即等待PrepareRoundtrip()

  3. 中的3秒延迟

    实现这一目标的最佳方法是什么?谢谢!

    TL; DR:

    stateObject.Execute()添加一个包装器,以添加一个可能很长的额外准备步骤;需要整个事情来返回一个代表原始结果的Task,而不是等待准备步骤先完成。

2 个答案:

答案 0 :(得分:1)

  1. 使用UnwrapTask<Task>(这就是您所拥有的)转换为表示内部Task完成的Task,而无需同步等待外部任务完成。

  2. 只需await Task<Task>两次,而不是一次,如果是async方法。

答案 1 :(得分:0)

你根本不应该使用ContinueWith。它是一种具有危险行为的过时方法(具体来说,它将使用当前的任务调度程序)。

相反,只需使用await

private Task ExecuteWithPrepareAsync()
{
  if (!PrepareEnabled)
    return stateObject.ExecuteAsync();
  else
    return PrepareAndExecuteAsync();
}

private async Task PrepareAndExecuteAsync()
{
  await PrepareRoundtripAsync();
  await stateObject.ExecuteAsync();
}

另请注意Async命名惯例part of the TAP pattern