我有一个多线程应用程序,它使用静态方法写入设置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
}
}
}
}
答案 0 :(得分:40)
您应该创建一个单独的静态锁定对象并使用它。不要使用一个字符串!字符串会自动实现,每个编程声明的字符串只有一个实例,因此您无法保证对该锁的独占访问权。
你应该这样做:
public class A {
private static Object LOCK = new Object();
private static void foo() {
lock(LOCK) {
// Do whatever
}
}
}
(语法可能不正确;我主要是Java人员,但关于锁定和字符串实习的相同规则适用于C#)
lock关键字强制执行互斥锁:一次只能有一个线程锁定任何特定对象。如果第二个线程调用foo
,那么它将阻塞,直到第一个线程退出锁定块。
带回家消息:对私有静态变量进行静态方法锁定。不要锁定字符串或typeof(...),因为你无法保证没有其他人正在使用该对象。始终锁定一个你知道不会被其他任何人触及的对象,将其设为私有并使其成为新的。
答案 1 :(得分:33)
lock()的概念是使用它可以引用的现有对象来控制是否授予访问权。
static object SpinLock = new object();
lock(SpinLock)
{
//Statements
}
当执行离开lock()块时,引用被释放,并且等待执行代码块的任何其他线程可以继续(当然,一次一个)。