我理解来自MSDN的锁定关键字的主要功能
lock语句(C#参考)
lock关键字通过获取给定对象的互斥锁,执行语句,然后释放锁来将语句块标记为关键部分.
什么时候应该使用锁?
例如,它对多线程应用程序有意义,因为它可以保护数据.但是,当应用程序没有关闭任何其他线程时,它是否有必要?
使用锁存在性能问题吗?
我刚刚继承了一个在任何地方使用锁的应用程序,它是单线程的,我想知道我应该留下它们,它们甚至是必要的吗?
请注意,这更多是一般知识问题,应用程序速度很好,我想知道这是否是将来要遵循的良好设计模式,或者除非绝对需要,否则应该避免这种情况.
什么时候应该使用锁?
应使用锁来保护多线程代码中的共享资源.不是别的.
但是,当应用程序没有关闭任何其他线程时,它是否有必要?
绝对不.这只是浪费时间.但是请确保您没有隐式使用系统线程.例如,如果您使用异步I/O,您可能会收到来自随机线程的回调,而不是原始线程.
使用锁存在性能问题吗?
是.它们在单线程应用程序中不是很大,但为什么要拨打你不需要的电话呢?
...如果这是一个很好的设计模式,将来会跟进[?]
无所事事地锁定一切都是一种糟糕的设计模式.如果您的代码混乱了随机锁定,然后您决定使用后台线程进行某些工作,那么您可能会遇到死锁.在多个线程之间共享资源需要仔细设计,并且越能分离出棘手的部分就越好.
这里的所有答案都是正确的:锁的用处是阻止线程同时访问锁定的代码.但是,这个领域有许多细微之处,其中之一就是公共语言运行时自动将锁定的代码块标记为关键区域.
代码被标记为关键的影响是,如果整个区域无法完全执行,运行时可能会认为您的整个Application Domain可能受到危害,因此会从内存中卸载它.引用MSDN:
例如,考虑一个尝试在持有锁时分配内存的任务.如果内存分配失败,则中止当前任务不足以确保AppDomain的稳定性,因为域中可能有其他任务正在等待同一个锁.如果当前任务终止,则其他任务可能会死锁.
因此,即使您的应用程序是单线程的,这可能对您有害.考虑锁定块中的一个方法抛出最终未在块内处理的异常.即使异常发生在它通过调用堆栈冒泡时,您的关键代码区域也无法正常完成.谁知道CLR会如何反应?
有关更多信息,请阅读本文关于Thread.Abort()的危险.
请记住,可能有原因导致您的应用程序不像您想象的那样是单线程的.例如,.NET中的异步I/O可能会在池线程上回调,就像一些各种计时器类(不是Windows窗体计时器)一样.