等待Task.Delay()与Task.Delay().Wait() [英] await Task.Delay() vs. Task.Delay().Wait()

查看:603
本文介绍了等待Task.Delay()与Task.Delay().Wait()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,我有以下两个简单示例:

In C# I have the following two simple examples:

[Test]
public void TestWait()
{
    var t = Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Start");
        Task.Delay(5000).Wait();
        Console.WriteLine("Done");
    });
    t.Wait();
    Console.WriteLine("All done");
}

[Test]
public void TestAwait()
{
    var t = Task.Factory.StartNew(async () =>
    {
        Console.WriteLine("Start");
        await Task.Delay(5000);
        Console.WriteLine("Done");
    });
    t.Wait();
    Console.WriteLine("All done");
}

第一个示例创建一个打印开始"的任务,等待5秒钟打印完成",然后结束该任务.我等待任务完成,然后打印全部完成".当我运行测试时,它按预期运行.

The first example creates a task that prints "Start", waits 5 seconds prints "Done" and then ends the task. I wait for the task to finish and then print "All done". When I run the test it does as expected.

第二个测试应该具有相同的行为,但是由于使用async和await,因此Task内部的等待应该是非阻塞的.但是此测试只会打印开始",然后立即打印全部完成"和完成".

The second test should have the same behavior, except that the waiting inside the Task should be non-blocking due to the use of async and await. But this test just prints "Start" and then immediately "All done" and "Done" is never printed.

我不知道为什么会出现这种行为:S非常感谢您的帮助:)

I do not know why I get this behavior :S Any help would be appreciated very much :)

推荐答案

第二个测试有两个嵌套任务,您正在等待最外部的任务,要解决此问题,必须使用t.Result.Wait(). t.Result获取内部任务.

The second test has two nested tasks and you are waiting for the outermost one, to fix this you must use t.Result.Wait(). t.Result gets the inner task.

第二种方法大致相当于:

The second method is roughly equivalent of this:

public void TestAwait()
{
  var t = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Start");
                return Task.Factory.StartNew(() =>
                {
                    Task.Delay(5000).Wait(); Console.WriteLine("Done");
                });
            });
            t.Wait();
            Console.WriteLine("All done");
}

通过调用t.Wait(),您正在等待最外部的任务,该任务立即返回.

By calling t.Wait() you are waiting for outermost task which returns immediately.

处理此情况的最终正确"方法是完全放弃使用Wait而只使用await.将用户界面附加到异步代码后,Wait可能会导致死锁问题./p>

The ultimately 'correct' way to handle this scenario is to forgo using Wait at all and just use await. Wait can cause deadlock issues once you attached a UI to your async code.

    [Test]
    public async Task TestCorrect() //note the return type of Task. This is required to get the async test 'waitable' by the framework
    {
        await Task.Factory.StartNew(async () =>
        {
            Console.WriteLine("Start");
            await Task.Delay(5000);
            Console.WriteLine("Done");
        }).Unwrap(); //Note the call to Unwrap. This automatically attempts to find the most Inner `Task` in the return type.
        Console.WriteLine("All done");
    }

最好使用Task.Run开始异步操作:

Even better just use Task.Run to kick off your asynchronous operation:

    [TestMethod]
    public async Task TestCorrect()
    {
        await Task.Run(async () => //Task.Run automatically unwraps nested Task types!
        {
            Console.WriteLine("Start");
            await Task.Delay(5000);
            Console.WriteLine("Done");
        });
        Console.WriteLine("All done");
    }

这篇关于等待Task.Delay()与Task.Delay().Wait()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆