这不是矫枉过正,只有其中一项必要吗?我搜索过并发现了有关互斥的不同帖子以及C#here和here中的锁定。
例如:
在我们的应用程序中,我们有一个旋转多个重新连接线程的函数,在这个线程中我们使用Mutex
和lock
。不会lock
阻止访问此部分代码并阻止connect
被任何其他线程更新?
bool connect = false;
Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key);
try
{
lock(site)
{
if(site.ContainsKey(key))
{
siteInfo = (SiteInfo)site[key];
if(reconnectMutex.WaitOne(100, true))
{
connect = true;
}
}
}
if (connect)
{
// Process thread logic
}
}
catch
{}
reconnectMutex.ReleaseMutex();
更多信息:
这是在不在Web Garden中运行的ASP.NET WebService中。
答案 0 :(得分:11)
Mutex(因为它有一个名字)将停止访问它的同一台机器上的任何进程,而lock只会停止同一进程中的其他线程。我无法从该代码示例中看到为什么您需要这两种锁。在短时间内保持简单锁定似乎是一种好习惯 - 但是更重的进程间互斥锁被锁定的时间可能更长(虽然重叠)!使用互斥锁会更简单。也许要找出是否真的需要进程间锁。
顺便说一句,在这种情况下使用catch {}
绝对是错误的。您应该使用finally { /* release mutex */ }
。他们是非常不同的。 catch会吞下更多种类的异常,并且还会导致嵌套的finally处理程序执行以响应低级异常,例如内存损坏,访问冲突等。所以代替:
try
{
// something
}
catch
{}
// cleanup
你应该:
try
{
// something
}
finally
{
// cleanup
}
如果您可以从中恢复特定的例外,您可以抓住它们:
try
{
// something
}
catch (DatabaseConfigurationError x)
{
// tell the user to configure the database properly
}
finally
{
// cleanup
}
答案 1 :(得分:3)
“lock”基本上只是Montor.Enter / Exit的语法糖。 Mutex是一个多进程锁。
他们的行为非常不同。在同一个应用程序或方法中使用它们没有任何问题,因为它们旨在阻止不同的事物。
但是,在你的情况下,我认为你可能会更好地研究Semaphore和Monitor。听起来你不需要锁定进程,因此在这种情况下它们可能是更好的选择。
答案 2 :(得分:2)
正如其他人所指出的,Mutex跨进程锁定,本地锁(Monitor)仅锁定当前进程拥有的那些线程。但是......
您展示的代码有一个非常严重的错误。看起来你最后无条件释放了Mutex(即reconnectMutex.ReleaseMutex()
),但只有当site.ContainsKey()
返回true
时才会获取互斥锁。
因此,如果site.ContainsKey
返回false
,则释放互斥锁会抛出ApplicationException
,因为调用线程不拥有互斥锁。
答案 3 :(得分:1)
你没有提供足够的信息来真正回答这个问题。正如Earwicker已经说明的那样,Mutex允许您在进程间进行同步。因此,如果您运行同一个应用程序的两个实例,则可以序列化访问。例如,在使用外部资源时,您可以执行此操作。
现在,您锁定站点可以保护站点不被同一进程中的其他线程访问。这可能是nessecary,具体取决于其他方法/线程正在做什么。现在,如果这是唯一一个网站被锁定的地方,那么我认为这是过度杀伤。