繁体   English   中英

为什么 Thread.Sleep 有效而 Task.Delay 无效?

[英]Why does Thread.Sleep work but Task.Delay does not?

在我的代码中,我假设outerFlag将在innerFlag之后被击中,但它实际上innerFlag运行而忘记( innerFlagouterFlag之后被击中)。 当我使用Thread.Sleep而不是Task.Delay标志按正确顺序命中。

这是代码:

[Test]
public async Task Test() {

    bool innerFlag = false;
    bool outerFlag = false;

    await Lock(async () => {
        await Task.Delay(2000);
        innerFlag = true;
    });

    outerFlag = true;

    Thread.Sleep(1000);
    Thread.Sleep(2500);
}

private Task Lock(Action action) {
    return Task.Run(action);
}

我还注意到,当我调用Task.Delay并在没有Lock方法的情况下设置innerFlag ,但通过直接 lambda,它按预期工作。

有人可以解释这种行为吗?

您的Lock方法不理解异步委托,因此您尝试作为参数传递的异步委托被视为async void Async voids 在各种方面都有问题, 应该避免,除非它们被用作其预期目的,作为事件处理程序。

为了确保您的方法理解异步委托,您必须创建一个接受Func<Task>作为参数的重载:

private Task Lock(Func<Task> func)
{
    return Task.Run(func);
}

请注意, func参数可以直接传递给Task.Run ,因为此方法也理解异步委托。 并非所有内置方法都理解异步委托,值得注意的例子是Task.Factory.StartNewParallel.ForEach 每次在委托中添加async修饰符时都必须小心。 您必须确保被调用的方法理解异步委托,否则最终可能会出现异步无效和它们造成的破坏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM