发布模式下的C#mutex与调试模式下的行为不同

时间:2014-05-07 18:26:03

标签: c# debugging mutex release

所以我有以下代码:

...
private static void Main(string[] args)
{
    string file=DateTime.Now.ToFileTime().ToString();
    File.AppendAllText(file, "Mutex\r\n");

    bool CreatedNew;
    Mutex mutex=new Mutex(true, AppDomain.CurrentDomain.FriendlyName, out CreatedNew);

    if(CreatedNew)
    {
        #if DEBUG
        File.AppendAllText(file, "Launching in DEBUG mode\r\n");
        #else
        File.AppendAllText(file, "Launching in RELEASE mode\r\n");
        #endif

        //Program.Launch();
        Program.ProcessArgsAndLaunch(args);
    }
    else
    {
        File.AppendAllText(file, "Handling dupe\r\n");
        Program.HandleDuplicate();
    }
}
...

我在这里检查过无数文章,其他网站没有运气。

基本上,代码检查应用程序的运行实例,如果有,则切换到正在运行的实例的主窗口。如果没有,它会启动应用程序。

Debug模式下,这一切都按预期工作,当我将配置切换到Release时问题就开始了:应用程序始终启动(Mutex似乎无所事事。)

我添加了有条件编译的转储,显示应用程序在哪种模式下启动,输出根据配置发生变化,但遗憾的是,应用程序的行为也是如此。

这可能是race condition,但我不确定。

如果需要,我们会发布更多代码。

感谢。

2 个答案:

答案 0 :(得分:13)

在Juan的回答中,在调试器内部和外部启动之间的垃圾收集方面存在差异。这与调试配置与发布配置并不完全相同,但无论如何你都应该注意这一点。

在调试器中,局部变量将作为其整个范围的GC根目录 - 但是当您未进行调试时,您的mutex变量根本不是GC根,因为您初始化后不要使用。这意味着您的Mutex可以立即进行垃圾收集(因此本地互斥锁将被释放)。

您应该使用using语句明确在合适的时间处置Mutex

// Note that you don't need a variable here... you can have one if you
// want though
using (new Mutex(...))
{
    // Code here to be executed while holding the mutex
}

答案 1 :(得分:8)

如果您有一个实例作为Debug运行而另一个实例作为Release运行,它们将不会共享相同的互斥锁,因为AppDomain.CurrentDomain.FriendlyName根据托管进程是否处于活动状态而不同。

如下所示:http://msdn.microsoft.com/en-us/library/ms242202.aspx