C#中的锁和互斥锁应该一起使用吗
这难道不是太过分了,而且只需要其中一个吗?我在C#和中搜索并找到了关于互斥和锁的不同帖子。C#中的锁和互斥锁应该一起使用吗,c#,locking,mutex,C#,Locking,Mutex,这难道不是太过分了,而且只需要其中一个吗?我在C#和中搜索并找到了关于互斥和锁的不同帖子。 示例: 在我们的应用程序中,我们有一个功能,可以剥离多个重新连接线程,在这个线程中,我们使用互斥锁和锁。是否会锁定阻止对这段代码的访问,并阻止任何其他线程更新连接 bool connect = false; Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key); try { lock(site) { if(site
示例:
在我们的应用程序中,我们有一个功能,可以剥离多个重新连接线程,在这个线程中,我们使用
互斥锁和锁。是否会锁定
阻止对这段代码的访问,并阻止任何其他线程更新连接
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();
更多信息:
这是在ASP.NET Web服务中,而不是在Web花园中运行。该互斥锁(因为它有一个名称)也会停止同一台机器上访问它的任何进程,而lock只会停止同一进程中的其他线程。我无法从代码示例中看出为什么两种锁都需要。在短时间内保持简单锁似乎是一种很好的做法,但随后更重的进程间互斥锁被锁定的时间可能更长(尽管重叠)!只使用互斥锁会更简单。也许是为了弄清楚进程间锁是否真的有必要
顺便说一下,catch{}
在这种情况下使用绝对是错误的。您应该使用最后{/*release mutex*/}
。他们非常不同。捕获将吞下比它应该吞下的种类多得多的异常,还将导致嵌套的finally处理程序执行,以响应低级异常,例如内存损坏、访问冲突等。因此,不要:
try
{
// something
}
catch
{}
// cleanup
你应该:
try
{
// something
}
finally
{
// cleanup
}
如果存在可以从中恢复的特定异常,您可以捕获它们:
try
{
// something
}
catch (DatabaseConfigurationError x)
{
// tell the user to configure the database properly
}
finally
{
// cleanup
}
“lock”基本上只是Montor.Enter/Exit的语法糖。互斥锁是一种多进程锁
他们有非常不同的行为。在同一个应用程序或方法中使用这两种方法并没有什么错,因为它们是为阻止不同的事情而设计的
然而,在您的情况下,我认为您最好查看信号量和监视器。听起来您不需要跨进程锁定,因此在这种情况下,它们可能是更好的选择。您没有提供足够的信息来真正回答这个问题。正如Earwicker所说的,互斥允许跨进程进行同步。因此,如果运行同一应用程序的两个实例,则可以序列化访问。例如,您可以在使用外部资源时执行此操作
现在,您可以锁定站点,以防止同一进程中的其他线程访问该站点。这可能取决于其他方法/线程正在执行的操作。现在,如果这是站点被锁定的唯一位置,那么是的,我认为这是过分的。正如其他人所指出的,互斥锁跨进程锁定,而本地锁(监视器)只锁定当前进程拥有的线程。然而
您显示的代码有一个相当严重的错误。看起来您在最后无条件释放互斥体(即,重新连接互斥体。ReleaseMutex()
),但只有当site.ContainsKey()
返回true
时,才会获取互斥体
因此,如果site.ContainsKey
返回false
,那么释放互斥锁将抛出ApplicationException
,因为调用线程不拥有互斥锁。它必须被相应地命名为特定于机器的。这一点很好,我希望在第一句话中已经澄清了这一点。你是说我应该删除catch语句并用finally替换它吗?是的。如果“进程线程逻辑”代码抛出了可以恢复的内容,那么您可能也需要捕获,但是您应该只捕获可以恢复的内容。一般来说,“catch{}Foo();”是实现“finally{Foo();}”设计目标的错误方法。我在答案中更清楚地说明了这一点,尽管它与主题无关-它可能比重复锁定问题更重要!谢谢-我在发布这篇文章后发现了这个bug。我不明白为什么应用程序刚刚关闭——这就是问题所在。