C#Task.Run不等待动作变量

时间:2018-06-18 00:39:37

标签: c# lambda async-await task

参见示例代码。

Console.WriteLine("start")
Task.Run(async () =>
{
    await Task.Delay(3000);
});
Console.WriteLine("end");

// result 
// start [3s delay] end

有效! 但是下面的代码不起作用。

Action action = async () =>
{
    await Task.Delay(3000);
};
Console.WriteLine("start")
Task.Run(action);
Console.WriteLine("end");

// result
// start [without delay] end

为什么Task.Run不等待异步操作变量?

编辑-------------------------

我很抱歉。我写错了代码。 这是正确的代码。

我在VS 2017的C#Interactive上测试

Console.WriteLine("start");
await Task.Run(async () =>
{
    await Task.Delay(3000);
});
Console.WriteLine("end");

Action action = async () =>
{
    await Task.Delay(3000);
};
Console.WriteLine("start");
await Task.Run(action);
Console.WriteLine("end");

4 个答案:

答案 0 :(得分:0)

使用async和Tasks的主要原因是使两个或多个方法同时运行。因此,您的方法将继续运行,当完成延迟后,将在延迟后调用任何内容,因为您在任务中运行另一个异步函数。

如果您运行此方法,您会注意到

  

完成

将打印在其他作品的中间(此处其他作品为for loop

Console.WriteLine("start");
Task.Run(async () =>
 {
     await Task.Delay(200);
      Console.WriteLine("Finished");
 });

 for(int i = 0; i < 500; i++)
    {
       Console.WriteLine(i);
    }
Console.WriteLine("end");
Console.ReadKey();
  

出于某种原因,它在dotnetfiddle上没有按预期工作

即使你没有在任务中运行异步,它们也会同时运行。

看看这个例子:

 Console.WriteLine("start");
            Task.Run(() =>
            {
                Task.Delay(2000).Wait(); // Will NOT wait !
                Console.WriteLine("Finished");
            });

            for(int i = 0; i < 500; i++)
            {
                Console.WriteLine(i);
            }
            Console.WriteLine("end");
            Console.ReadKey();
  

它会继续,因为它在任务

上没有任何延迟

但是如果你想让方法等待,首先:不要在任务上运行它。 第二:调用Wait()方法。

喜欢:

Console.WriteLine("start");

Task.Delay(2000).Wait(); // It'll wait for 2 seconds before continue.

for(int i = 0; i < 500; i++)
  {
     Console.WriteLine(i);
  }
 Console.WriteLine("end");
 Console.ReadKey();

答案 1 :(得分:0)

在没有等待的情况下使用Task.Run时,这只会触发并忘记&#39;。代码执行不会等待它,只要thread thread poolTask,它就会立即运行。

通常,如果您想卸载某些工作并等待完成该工作,请创建一个单独的方法,返回await,然后Console.WriteLine("start") await DoWorkAsync(); Console.WriteLine("end"); ///////// private Task DoWorkAsync() { return Task.Run(async () => { await Task.Delay(3000); }); }

示例

Task

请注意,不建议将方法主体包装到Tasks并将其返回,这通常会导致一些代码异味。

Stephen Cleary拥有关于async/await和{{1}}的良好信息。我会读到这个:

https://blog.stephencleary.com/2012/02/async-and-await.html

答案 2 :(得分:0)

将像这样工作,虽然不是那么明显:

Func<Task> action = async () =>
{
    await Task.Delay(3000);
};

Console.WriteLine("start");
await Task.Run(action);
Console.WriteLine("end");

答案 3 :(得分:-2)

你可以试试这个:

Action action = async () =>
                {
                    await Task.Delay(3000);
                };
                Console.WriteLine("start");
                Task.Run(action).Wait();                
                Console.WriteLine("end");