为什么C#lock不能用于长时间操作?

Łuk*_*kup 2 c# asynchronous locking

很多文章说:不要使用锁来同步长操作,我遵循这条规则.但我很好奇它到底有什么不妥?这是关于一些宝贵的资源消耗?

另外,如果我使用AutoResetEvent会有帮助吗?或者我宁愿忘记锁定长操作并进行异步编程?

Eri*_*ert 16

首先,如果你不理解规则的原因,那么你就是货架式编程.这是至关重要的,你了解这些规则的原因,而不是盲目地应用它们.

因此,有两个原因可以在很短的时间内保持锁定:

(1)长锁等性能差.假设您拥有一次只能有一个人可以使用的资源.你真的希望你的室友在淋浴时看着netflix吗?不,你希望他们进入并离开,以便其他人可以使用它.

(2)长锁等死锁.如果你长时间处于锁定状态,那么你可能会调用大量代码.这会增加您调用的代码具有您不知道的锁定顺序反转的几率.

因此,标准建议是:锁定尽可能少的时间,并且具有许多细粒度锁而不是单个粒度锁.

当然,标准的建议就是有许多细粒度锁增加了死锁的机会,因为现在你有可能被颠倒的锁.并且有许多细粒度的锁也增加了一个未知的种族的可能性,在这两个锁定的区域之间有一些你没有考虑过的东西.因此标准建议是:拥有少量粗粒度锁,可锁定大部分代码.

标准建议是矛盾的.这是为什么?因为通过监视器锁定管理多线程程序中的共享内存基本上是一个坏主意.这是标准做法,但这并不能使它变好.

另外,如果我使用AutoResetEvent会有帮助吗?或者我宁愿忘记锁定长操作并进行异步编程?

我的建议是尽可能使用最高级别的操作.如果你可以在没有异步的情况下逃脱,那就去做吧.如果不是,请考虑进程级并行或单线程异步,具体取决于您是处理器绑定还是IO延迟限制.如果那些因为某种原因不起作用,那么将线程视为没有共享内存的轻量级进程; 使用TPL为您管理线程.

等等.处理锁定或互锁操作或挥发性应该是最后的手段,这些工具应该用作构建更高级别工具的原语.

  • @adrianm:你的问题是:如果我们说"在我们的场景中没有问题",那么有问题吗?不,如果您不关心性能或正确性,那么根据定义,您没有性能或正确性问题. (3认同)