Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的锁和互斥锁应该一起使用吗_C#_Locking_Mutex - Fatal编程技术网

C#中的锁和互斥锁应该一起使用吗

C#中的锁和互斥锁应该一起使用吗,c#,locking,mutex,C#,Locking,Mutex,这难道不是太过分了,而且只需要其中一个吗?我在C#和中搜索并找到了关于互斥和锁的不同帖子。 示例: 在我们的应用程序中,我们有一个功能,可以剥离多个重新连接线程,在这个线程中,我们使用互斥锁和锁。是否会锁定阻止对这段代码的访问,并阻止任何其他线程更新连接 bool connect = false; Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key); try { lock(site) { if(site

这难道不是太过分了,而且只需要其中一个吗?我在C#和中搜索并找到了关于互斥和锁的不同帖子。

示例:
在我们的应用程序中,我们有一个功能,可以剥离多个重新连接线程,在这个线程中,我们使用
互斥锁和
锁。
是否会锁定
阻止对这段代码的访问,并阻止任何其他线程更新
连接

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。我不明白为什么应用程序刚刚关闭——这就是问题所在。