Lock()在静态方法中

koe*_*oen 19 c# locking

我有一个多线程应用程序,使用静态方法写入设置xml文件.我想避免文件同时更新两次(导致访问/写入异常).

我怎么做?

这不起作用:

namespace Program
{
    public class Settings
    {
        private static void SetSettingsValue (string settings, string value)
        {
            // make this thread safe to avoid writing to a locked settings xml file
            lock (typeof(Settings))
            {
                //write data to xml file
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Cam*_*ner 40

您应该创建一个单独的静态锁定对象并使用它.不要使用一个字符串!字符串会自动实现,每个编程声明的字符串只有一个实例,因此您无法保证对锁定的独占访问权限.

你应该做这个:

public class A {
    private static Object LOCK = new Object();

    private static void foo() {
        lock(LOCK) {
            // Do whatever
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(语法可能不正确;我主要是Java人员,但关于锁定和字符串实习的相同规则适用于C#)

lock关键字强制执行互斥锁:一次只能有一个线程锁定任何特定对象.如果第二个线程调用foo则它将阻塞,直到第一个线程退出锁定块.

带回家消息:对私有静态变量的静态方法锁定.不要锁定字符串或typeof(...),因为你无法保证没有其他人正在使用该对象.始终锁定一个你知道不被其他任何人触及的对象,将其设为私有并使其成为新的.

  • 这是整个讨论中的最佳答案.因为Cameron足够明智地指定锁对于类是私有的. (3认同)

Eri*_*ren 36

lock()的概念是使用它可以引用的现有对象并用于控制是否授予访问权限.

static object SpinLock = new object();

lock(SpinLock)
{
   //Statements
}
Run Code Online (Sandbox Code Playgroud)

当执行离开lock()块时,释放引用,并且等待执行代码块的任何其他线程可以继续(当然一次一个).

  • 请注意,您无法更改lock()语句本身内的SpinLock引用.用于锁定的对象需要所有需要执行代码的线程都可以访问,并且每次都不能更改引用,或者线程永远不会相互阻塞,并且您将获得资源争用/冲突. (3认同)