【问题标题】:C# does a Mutex need a destructor?C# Mutex 需要析构函数吗?
【发布时间】:2017-06-02 11:22:49
【问题描述】:

我目前正在编写一个 WPF 应用程序,它注册一个 url 方案,该方案基本上将命令行参数传递给应用程序。现在的想法是只启动应用程序一次,如果单击附加链接,第一个启动的应用程序应该评估命令行。

由于我从来没有用 Mutex 做到这一点,我已经阅读了一些教程,现在我已经使用 MutexMemoryMappedFile 添加到我的 App 类中,如下所示:

public partial class App : Application
{
    Mutex m_Mutex;
    MemoryMappedFile m_File;

    protected override void OnStartup(StartupEventArgs e)
    {
         bool mutexCreated;
         Assembly assembly = Assembly.GetExecutingAssembly();
         string mutexName = $"local_{ assembly.GetType().GUID }";

         m_Mutex = new Mutex(true, mutexName, out mutexCreated);
         // Use user32.dll RegisterWindowMessage() to register a Message for the app.

         m_File = MemoryMappedFile.CreateOrOpen($"{mutexName}_mappedData", /* Other Parameters like Security Settings etc. */ );

         if(!mutexCreated)
         {
             m_Mutex = null;
             m_File = null;
             // Use user32.dll PostMessage() to broadcast to all Apps.
             App.Current.Shutdown();
         }
         else
         {
             this.MainWindow = new MainWindow();
             this.MainWindow.Show();
         }
    }
}

现在可以正常工作了,我可以使用PostMessage 广播在应用程序之间轻松传递数据。

现在Mutex 类的MSDN reference 在示例中添加了一个析构函数。我的教程没有这样做。

~App()
{
    m_Mutex?.Dispose();
    m_File?.Dispose();
}

我现在尝试使用和不使用析构函数进行编译 - 甚至故意使应用程序崩溃,但我没有看到任何区别。在应用程序的基本实例崩溃后,Windows 似乎已经处理掉了 Mutex。当我再次启动应用程序时,它确实创建了一个新的互斥体并且应用程序启动了新窗口。任何进一步的应用启动都会正确引用该 Mutex 并向新窗口发送消息。

在我看来,无论是否使用终结器,GC 似乎已经在清理。现在我的问题是,那个特定的析构函数的目的到底是什么,有必要吗?

【问题讨论】:

  • 你不需要在 C# 中清理任何东西,正是因为 GC;除非它是本机资源,在这种情况下你应该实现 IDisposable 然后一切都应该与 using 语句一起使用。 --- IGNORE:您在lock 关键字或Monitor(哪个锁环绕)上使用互斥锁是否有原因? --- 没有注意到您正在使用内存映射文件。
  • @Bauss 在当前设计中,每个链接都会启动应用程序的一个新实例,我需要在应用程序之间进行跨实例消息传递。到目前为止,我曾经创建一个本地套接字,但总是遇到一些防火墙问题。现在我已经通过 Mutex 和 WindowsMessagingQueue 尝试了这种方法。这很好用,但我不确定为什么 MSDN 引用在 GC 似乎处理它时有析构函数。我想,由于我注册了一个系统范围的互斥体,它可能确实需要销毁该引用,否则操作系统会将其保存在内存中,但似乎并非如此。
  • 这是一个重复的问题。看到这个:stackoverflow.com/questions/7107079/should-i-dispose-a-mutex

标签: c# wpf mutex destructor


【解决方案1】:

最好在使用完任何实现IDisposable 接口的对象后立即处理它。

但是,当您的应用程序(进程)结束时,互斥锁将被操作系统自动销毁,因此在实践中,如果您在整个生命周期中都使用互斥锁,是否真的处置互斥锁并不会产生太大影响您的申请(流程)。

但如果您想遵守良好的编码标准并避免代码分析警告,您应该丢弃它。

【讨论】:

    猜你喜欢
    • 2013-05-22
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    相关资源
    最近更新 更多