当前位置: 首页 > 知识库问答 >
问题:

等待任务。延迟()与任务。延迟().等待()

司马英才
2023-03-14

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

[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秒钟打印“完成”,然后结束任务。我等待任务完成,然后打印“全部完成”。当我运行测试时,它会按预期运行。

第二个测试应该具有相同的行为,只是由于使用了async和Wait,任务内部的等待应该是非阻塞的。但是这个测试只打印“开始”,然后立即打印“全部完成”和“完成”,永远不会打印。

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

共有1个答案

耿永寿
2023-03-14

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

第二种方法大致相当于:

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()您正在等待立即返回的最外层任务。

处理这种情况的最终“正确”方法是完全放弃使用Wait,而只使用Wait<代码>等待一旦将UI附加到异步代码,可能会导致死锁问题。

    [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");
    }

最好使用任务。运行启动异步操作:

    [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");
    }

 类似资料:
  • 我写了一个多线程应用程序,它广泛使用了async/await。它应该在预定的时间下载一些东西。为此,它使用了“await task.delay”。有时它每分钟发送数千个请求。 它按预期工作,但有时我的程序需要记录一些大的东西。这样做时,它会序列化许多对象并将它们保存到一个文件中。在那段时间里,我注意到我预定的任务执行得太晚了。我已经将所有日志记录放到一个具有最低优先级的单独线程中,这样问题就不再经

  • 问题内容: 我如何将while循环延迟到1秒的间隔,而又不将正在运行的整个代码/计算机的速度减慢到1秒钟的延迟(只是一个小循环)。 问题答案:

  • 我在网上搜索了很多关于vs await async,但是在这个特定的使用场景中,我并不真正理解其中的区别。我相信情况很简单。 vs. 其中,是一个异步方法,其中包含一些异步调用,例如使用wait调用db。 问题: 在这种情况下,两者之间有什么区别吗?任何帮助或意见,谢谢!

  • 我试图对其运行黑盒测试的web应用程序可以使用ajax调用,但这些ajax调用在DOM上不呈现任何内容,因此我不能使用显式等待。此外,隐式只适用于语句,同样没有用处。 我成功地使用了,但我希望有更好的方法来延迟执行。

  • 我正试图实现一个轮询机制。我想根据一些条件增加或减少轮询间隔。我使用mono.repeat with delayElements来执行带有间隔的重复任务。但我无法根据一些条件找到修改延迟的方法。

  • 使用asyn/wait vs wait有什么区别task.run() 等待任务。运行示例- 异步等待示例-