1

I'm currently writing a WPF app, that registers a url scheme which basically passes command line arguments to the app. Now the idea is to only start the app once and if an additional link is clicked, the first started app should evaluate the command line.

Since I've never done that with a Mutex I've read a few tutorials and now I've programmed it with Mutex and a MemoryMappedFile added to my App class like the following:

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();
         }
    }
}

This now works fine and I can pass the data easily between applications using the PostMessage broadcast.

Now the MSDN reference for the Mutex class has a Destructor added in the example. The tutorial I've had didn't do that.

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

I've tried it now compiling with and without the Destructor - even crashing the app on purpose, but I've not seen any difference. After the base instance of the app crashed, Windows seems to have disposed of the Mutex. At leased when I started the App again, it did create a new Mutex and the app started the new window. Any further app starts were correctly referencing that Mutex and messaging to the new window.

To me it seems that the GC is already cleaning up, with or without the finalizer in place. Now my question is, what exactly is the purpose of that specific Destructor, and is it necessary?

Adwaenyth
  • 2,020
  • 12
  • 24
  • You don't need to cleanup anything in C#, exactly because of GC; unless it's native resources in which case you should implement `IDisposable` and then everything should be used with `using` statements. --- IGNORE: Is there a reason why you're using a mutex over the `lock` keyword or `Monitor` (Which lock wraps around)? --- didn't notice you're using memory-mapped files. – Bauss Jan 18 '17 at 07:17
  • @Bauss in the current design, each link starts a new instance of the app and I need cross instance messaging between the apps. So far I used to create a local socket, but than always had some firewall issues. Now I've tried the approach via the Mutex and WindowsMessagingQueue. That works nicely but I wasn't sure about why MSDN reference has the destructor in place when the GC seems to handle it. I thought since I registered a system wide Mutex it did probably need to destroy that reference otherwise the OS will keep it in memory, but that doesn't seem to be the case. – Adwaenyth Jan 18 '17 at 07:22
  • Related: http://stackoverflow.com/questions/7107079/should-i-dispose-a-mutex – grek40 Jan 18 '17 at 08:06
  • This is a duplicate question. See this one: http://stackoverflow.com/questions/7107079/should-i-dispose-a-mutex – akrabi Jan 18 '17 at 08:11

1 Answers1

2

It is a good practice to always dispose any object that implements the IDisposable interface as soon as you are done using it.

The mutex will however be automatically destroyed by the operating system when your application (process) ends so in practice it won't make much of a difference whether you actually do dispose the mutex or not if you use it for the entire lifetime of your application (process).

But if you want to comply with good coding standards and avoid code analysis warnings you should dispose it.

mm8
  • 163,881
  • 10
  • 57
  • 88