共享资源锁

我在.NET 4.5上使用C# – Web API Self Host。 服务器端我有一个非线程安全的进程:它可以一次处理一个请求。 如何在控制器代码中锁定此资源(进程),以便按顺序提供客户端,等待资源在使用之前被释放? 就像是:

while(true){ if(!process.isLocked) break; } lock(process) do(work) unlock(process) warn(others) 

任何代码段或建议都表示赞赏。 提前致谢。

如果您正在寻找要执行的每个线程,但一次只能查找一个,那么您可以将lock语句与静态对象一起使用:

 private static object lockobj = new object(); public void DoWorkWhenNotBusy() { lock (lockobj) { // do work Console.WriteLine("Working #1 (should always complete)..."); Thread.Sleep(500); } } 

如果你希望线程在对象被锁定时立即返回,那么你可以像这样写(双重检查锁定):

 private static object lockobj2 = new object(); private volatile bool locked = false; public void DoWorkIfNotBusy() { if (!locked) { lock (lockobj2) { if (!locked) { locked = true; // do work Thread.Sleep(500); Console.WriteLine("Working #2 (only if not busy)..."); } locked = false; } } } 

测试示例:

 for (int i = 0; i < 10; i++) { var ts = new ThreadStart(DoWorkWhenNotBusy); Thread t = new Thread(ts); t.Start(); var ts2 = new ThreadStart(DoWorkIfNotBusy); Thread t2 = new Thread(ts2); t2.Start(); Console.WriteLine("{0} started", i); } 

我想在这里扩展dbaseman的答案。 具体来说,他的DoWorkIfNotBusy方法。

我认为这是一个不好的例子(由于可能的竞争条件),并且想表明我认为正确方式的方式:

 private static object lockobj = new object(); public bool DoWorkIfNotBusy() { bool lockWasTaken = false; var temp = lockobj; try { Monitor.TryEnter(temp, ref lockWasTaken); { //Do work here.. //Believe it or not, the brackets in which this work is in is important. //The brackets are to resolve a race condition. } } finally { if (lockWasTaken) Monitor.Exit(temp); } return lockWasTaken; }