2015-01-26 36 views
1

我试图松散地为我的网站实现自己的“锁定”或“互斥锁”。为此,我使用isLocked属性让服务器知道是否有其他用户正在运行更新。我想初始化它的值一次,但我不知道我的解决方案是否会这样做。下面是完整的例子:何处初始化MVC模型中的静态属性并执行锁定

在模型:

public abstract class BaseModel 
{ 
    public static bool isLocked = false; 
} 

当我使用的属性:

public class OtherModel : BaseModel 
{ 
    public OtherModel() : base() 
    { 
     if (/*condition &&*/ !BaseModel.isLocked) 
     { 
      BaseModel.isLocked = true; 
      //update 
      BaseModel.isLocked = false; 
     } 
    } 
} 

将服务器初始化isLocked一次(第一次BaseModel被实例化)或我需要在Global.asx文件中设置其值吗?

编辑:This was shared by @Michael更详细地解释了解决方案。

回答

2

是的,服务器将初始化isLocked一次。但是,你有更大的问题。这里有一个竞赛条件。

当您检查isLocked是否为true并且您将isLocked设置为true时,可能另一个线程也可能检查isLocked,并发现它为false,并且您可能会将它设置为true并认为两者都为true静态锁定。

这就是为什么你不应该使用这样的方法来锁定。而是使用一个静态的对象,然后在C#lock语句那个对象上,像这样:

public class ViewModel 
{ 
    public static object lockObject = new Object(); 
} 

lock(Model.lockObject) 
{ 
    // do something... 
} 

如果您需要测试如果代码被锁定,然后使用Monitor.TryEnter。

if (Monitor.TryEnter(Model.lockObject)) 
{ 
    try 
    { 
     // use object 
    } 
    finally 
    { 
     Monitor.Exit(Model.lockObject); 
    } 
} 
+0

@ christo8989 - 你的更新不会改变任何东西..你仍然有竞争条件,你仍然需要使用原子锁定操作。 – 2015-01-26 23:25:17

+0

我明白了。我会试试这个。谢谢! (我重新编辑修改名称......) – christo8989 2015-01-26 23:25:27

+0

@ christo8989 - 你只需要小心,你锁定一个静态对象,如果你不这样做,并锁定一个本地的东西,那么你只会锁定一个只有该线程才能看到的变量,并将打败目的。 – 2015-01-26 23:26:46

1

是不是因为你没有在你想锁定的代码周围使用lock声明?

例如

public class ViewModel 
{ 
    public static Object Lock = new Object(); 
}   
public void Update() 
{ 
    lock (ViewModel.Lock) 
    { 
     //Perform updates 
    } 
} 

您可以查看已与使用lockhere,而不是我的随声已经回答了一个很好的答案。

+0

我以为锁是一个进程。 – christo8989 2015-01-26 23:16:30

+0

@ christo8989 - 是的,它是..和?无论如何,你不能从不同的进程访问你的ViewModel。 – 2015-01-26 23:17:49