C# 锁定跨多个线程使用的对象中的临界区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1881345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:37:02  来源:igfitidea点击:

Locking critical section in object used across multiple threads

c#locking

提问by Nathan

I've got a class that is instantiated within any number of threads that are spooled up as needed. This means that any number of instantiated versions of this class can be used at any one time, and there's a portion of this class that needs to be locked to prevent concurrent access.

我有一个在任意数量的线程中实例化的类,这些线程根据需要进行后台处理。这意味着在任何时候都可以使用该类的任意数量的实例化版本,并且需要锁定该类的一部分以防止并发访问。

To prevent data issues between the various threads, I needed a way to lock a section of code from the other instantiated versions of the class in other threads. Since there can be multiple instantiated versions of this class running around, I can't just use a private member variable to lock (and I know not to use the Type, or anything publicly accessible); so I used a private static member variable.

为了防止各个线程之间出现数据问题,我需要一种方法来锁定来自其他线程中类的其他实例化版本的一段代码。由于这个类可以有多个实例化版本,我不能只使用私有成员变量来锁定(而且我知道不要使用 Type 或任何可公开访问的东西);所以我使用了一个私有静态成员变量。

Is that a reasonable approach to this problem? Or is there a better solution?

这是解决这个问题的合理方法吗?或者有更好的解决方案吗?

Sample code below:

示例代码如下:

public class MyClass
  {
    private static object LockingVar = new object();

    public void MyPublicMethod()
    {
      lock (LockingVar)
      {
         // Do some critical code
      }
  }

EDIT

编辑

MyPublicMethod is making calls to a local SQLExpress instance, it can perform selects in addition to updates and inserts, so it needs to finish before another thread gets in there and mucks it up.

MyPublicMethod 正在调用本地 SQLExpress 实例,除了更新和插入之外,它还可以执行选择,因此它需要在另一个线程进入并将其搞砸之前完成。

采纳答案by RichardOD

Looks fine to me. I'd also mark the LockingVar as readonly.

对我来说看起来不错。我还将 LockingVar 标记为只读。

回答by Yann Schwartz

Yes, with your sample code, you'll achieve a global critical section on the method for all instances of the class.

是的,使用您的示例代码,您将获得该类所有实例的方法的全局临界区。

If that's what you're looking for (and you have to ask yourself if you really want to have only ever one thread running that method at a time), you can also use the [MethodImpl(MethodImplOptions.Synchronized)]which gets you basically the same feature.

如果这就是您要寻找的(并且您必须问自己是否真的希望一次只让一个线程运行该方法),您还可以使用 使[MethodImpl(MethodImplOptions.Synchronized)]您获得基本相同的功能。

[MethodImpl(MethodImplOptions.Synchronized)]
public static void MyPublicMethod()
{
     // Do some critical code
}

Note: this amounts to write lock(this){}if it's a instance method or lock(typeof(MyClass))if it's a class (static) method. Both are frown upon, so your lock(obj)pattern is better.

注意:lock(this){}如果它是一个实例方法或者lock(typeof(MyClass))它是一个类(静态)方法,这相当于写。两者都不受欢迎,所以你的lock(obj)模式更好。

回答by Rafa

From MSDN:

来自 MSDN:

Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.

最佳实践是定义要锁定的私有对象,或定义私有静态对象变量以保护所有实例共有的数据。

http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

Therefore your implementation seems to be right.

因此,您的实施似乎是正确的。