声明任务属性并等待它

时间:2017-03-29 14:37:46

标签: c# .net asynchronous lambda async-await

我陷入了一些我认为如此简单的事情,它让我脱离了自己。

我需要在某个时候声明一个任务并稍后再运行,我想到了:

Task T1 { get; set; }

public async Task CreateAndAwaitAsync()
{
    T1 = new Task(() => {
        // time consuming work like:
        System.Threading.Thread.Sleep(1000);
    }

    await T1;
}

当然lambda的主体和方法只是为了这个例子(正如我所说的,我需要稍后运行),但无论如何,await T1我无法进入lambda!我错过了什么?我感到很愚蠢,因为我已经使用了async-await范例已经很多年了,我甚至没有想到这不会起作用!

5 个答案:

答案 0 :(得分:4)

我认为可以在评论中回答,但最好提供更多信息。

await表示“等待此任务完成,然后完成其余工作”。您的示例中的任务未启动。 await不会为您启动它,因此整个方法只会停留在await,直到您开始执行任务。

即使使用当前代码,如果您稍后执行T1.Start() - 它将运行您的lambda并在完成后 - CreateAndAwaitAsync返回的任务也将完成。

否则 - 在创建任务时启动任务(Task.Run)或直接返回Task而不使用任何异步\ await:

public Task CreateAndAwaitAsync()
{
    T1 = new Task(() => {
        // time consuming work like:
        System.Threading.Thread.Sleep(1000);
    }
    // if you need to start it somewhere, do T1.Start();
    return T1;
}

答案 1 :(得分:2)

像@Evk所说,你需要调用T1.Start()

public async Task CreateAndAwaitAsync()
    {
        T1 = new Task(() =>
        {
            // time consuming work like:
            System.Threading.Thread.Sleep(1000);
        });

        T1.Start();
        await T1;
    }

答案 2 :(得分:1)

你没有开始这项任务。

示例:

public async Task DoSomething()
{
    await Task.Run(() => SomeMethod());
}

答案 3 :(得分:0)

您只是创建了一个await,但即使在此处使用Start(),它也无法运行。尝试T1 = Task.Run(your => lambda),或者您可以指定$variableName = "res" + $i New-Variable -Name $variableName -Value New-Object System.Windows.Forms.Label 然后等待它时它应该有用

答案 4 :(得分:0)

除非您正在进行CPU绑定工作,否则几乎不需要调用Task.Run,​​但可以使用async / await,如:

  public async Task DelayMe()
  {
    await Task.Delay(1000);
    await MoreAsyncThings();
  }

  Task T1 { get; set; }

  public async Task CreateAndAwaitAsync()
  {
    T1 = DelayMe();
    await T1;
  }

更新

为了存储代码供以后执行,我建议简单地使用lambda,如:

Func<Task> SomeWorkFactory()
{
  return async () => 
  { 
    await AsyncStuff(); 
    // More Stuff 
  };
}

var deferedWork = SomeWorkFactory();

// later somewhere else

await deferedWork(); 

所以基本上调用“SomeWorkFactory”创建工作包,但只调用Func执行它并返回一个等待的任务。

也许相关:

如果提供执行CPU绑定工作的方法(比如计算某些东西而不是等待回调),则不应该提供异步签名,而是将执行模式保留给调用者。主要是因为异步和并发是不同的概念。 Mads Torgersen在这里给出了一些见解:https://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B362并称之为“图书馆方法不应该谎言”(从第42分钟开始)

相关问题