[英]Why does Thread.Sleep work but Task.Delay does not?
在我的代码中,我假设outerFlag
将在innerFlag
之后被击中,但它实际上innerFlag
运行而忘记( innerFlag
在outerFlag
之后被击中)。 当我使用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.StartNew
和Parallel.ForEach
。 每次在委托中添加async
修饰符时都必须小心。 您必须确保被调用的方法理解异步委托,否则最终可能会出现异步无效和它们造成的破坏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.