我学会了从池线程调用Task.Wait会导致线程饥饿死锁的困难方法。
根据this MSDN article,在“死锁”一章中,我们应遵守这两条规则:
似乎唯一合法使用Task.Wait的地方是Main函数 - 我在这里夸大了一点,但你明白了。
为什么Task.Wait仍然是.NET框架的一部分,看它有多危险?
答案 0 :(得分:5)
为什么Task.Wait仍然是.NET框架的一部分,看看如何 危险吗?
因为您希望能够在Task
上同步阻止。很少,但你仍然这样做。如你所说,Main
可能是最受欢迎(最好是唯一)的地方。这一点,以及微软以其向后兼容性而臭名昭着的事实,因此一旦引入,它就不太可能被弃用或从BCL中消失。同样适用于Task.WaitAll
。
真正的问题当人们没有正确阅读文档并且不理解调用这种方法并最终滥用它的含义时,IMO就会启动。如果你仔细使用它,那就做得很好。
另一件事是你不能总是异步。不幸的是,很多时候你有代码,它是签名同步的,不能改变,需要调用异步方法调用。是的,这是危险的,并且被所有人劝阻,被认为是anti-pattern with async code,我自己已经回答了至少十二个关于SO的问题,人们最终陷入僵局并且不明白为什么,但TPL作者仍然需要使这些类型的电话成为可能。