C# C语言中的lock关键字#

C# C语言中的lock关键字#,c#,multithreading,design-patterns,locking,C#,Multithreading,Design Patterns,Locking,我从MSDN中了解了锁关键字的主要功能 锁定语句(C#参考) lock关键字标记语句 通过以下方式将块作为关键截面: 获取互斥锁 对于给定对象,执行 声明,然后发布 锁 什么时候应该使用锁 例如,它对多线程应用程序很有意义,因为它可以保护数据。但是,当应用程序不派生任何其他线程时,是否有必要 使用锁是否存在性能问题 我刚刚继承了一个到处都在使用锁的应用程序,它是单线程的,我想知道我是否应该将它们保留在其中,它们是必要的吗 请注意,这更多的是一个常识性问题,应用程序的速度很好,我想知道这是否是一个

我从MSDN中了解了锁关键字的主要功能

锁定语句(C#参考)

lock关键字标记语句 通过以下方式将块作为关键截面: 获取互斥锁 对于给定对象,执行 声明,然后发布 锁

什么时候应该使用锁

例如,它对多线程应用程序很有意义,因为它可以保护数据。但是,当应用程序不派生任何其他线程时,是否有必要

使用锁是否存在性能问题

我刚刚继承了一个到处都在使用锁的应用程序,它是单线程的,我想知道我是否应该将它们保留在其中,它们是必要的吗


请注意,这更多的是一个常识性问题,应用程序的速度很好,我想知道这是否是一个很好的设计模式,可以在将来遵循,或者除非绝对需要,否则应该避免这种情况。

一般来说,如果您的应用程序是单线程的,那么lock语句将不会有多大用处。由于不完全了解您的应用程序,我不知道它们是否有用——但我怀疑没有。此外,如果您的应用程序在任何地方都使用锁,我不知道我会对它在多线程环境中的工作有多大信心-原始开发人员是否真的知道如何开发多线程代码,或者他们只是在各处添加了锁语句,模糊地希望这能起到作用吗?

如果应用程序中只有一个线程,那么在应用程序中设置锁是没有意义的,是的,这是一个性能上的打击,尽管需要相当多的调用才能将这种打击累积成重要的东西

锁定变量可能会出现性能问题,但通常情况下,您会构造代码以最小化在“锁定”代码块中花费的时间长度


至于拆下锁。这将取决于代码到底在做什么。即使它是单线程的,如果您的对象是作为单实例实现的,那么您可能会有多个客户端同时使用它的一个实例(在内存中,在服务器上)。

是的,在使用锁时会有一些性能损失,但通常可以忽略不计

通常,只有在多线程场景中才需要使用锁(或任何其他互斥语句或构造),在多线程场景中,多个线程(您自己创建的或来自调用方的)有机会与对象交互并更改维护的基础状态或数据。例如,如果您有一个可由多个线程访问的集合,则您不希望一个线程在另一个线程尝试读取该集合时通过删除某个项目来更改该集合的内容。

锁定(令牌)仅用于标记不应在多个线程中同时运行的一个或多个代码块。如果您的应用程序是单线程的,那么它可以防止不可能存在的情况


锁定确实会调用性能影响,在执行代码之前添加指令以检查同时访问。它应该只在必要的地方使用。

锁应该在修改共享状态的代码周围使用,该状态由其他线程同时修改,并且这些其他线程必须使用相同的锁

锁实际上是一个内存访问序列化程序,线程(获取锁的线程)将等待锁进入,直到当前线程退出锁,所以内存访问被序列化

要回答您的问题,单线程应用程序中不需要锁,它确实会对性能产生副作用。因为C#中的锁是基于内核同步对象的,并且您使用的每个锁都会创建从用户模式到内核模式的转换

如果您对多线程性能感兴趣,最好从

什么时候应该使用锁

应该使用锁来保护多线程代码中的共享资源。没有别的事

但是,当应用程序不派生任何其他线程时,是否有必要

绝对不是。这只是浪费时间。但是,请确保您没有隐式使用系统线程。例如,如果您使用异步I/O,您可能会收到来自随机线程而不是原始线程的回调

使用锁是否存在性能问题

对。在单线程应用程序中,它们不是很大,但是为什么要进行不需要的调用呢

…如果这是一个很好的未来设计模式[?]


随意锁定所有东西是一种糟糕的设计模式。如果您的代码被随机锁定弄得乱七八糟,然后您决定使用后台线程进行某些工作,那么您很可能会遇到死锁。在多个线程之间共享资源需要仔细的设计,并且您越能隔离棘手的部分越好。

请记住,您的应用程序不像您想象的那样是单线程的,可能有一些原因。NET中的异步I/O很可能会回调池线程,例如,一些不同的计时器类(但不是Windows窗体计时器)也是如此。

请参阅C#中的关于“互斥体”部分。然后看看有关使用“lock(Object)”语句的问题。

这里的所有答案似乎都是正确的:locks的用途是阻止线程同时访问锁定的代码。然而,在这个领域有许多微妙之处,其中之一是被锁定的代码块被公共语言运行库自动标记为关键区域

标记为临界的代码的效果是,如果整个区域不能完全执行,运行时可能会认为整个应用程序域可能受到危害,因此,将其从内存中卸载。引述:

例如,考虑一个试图在保存锁的同时分配内存的任务。如果记忆