【发布时间】:2017-06-02 11:22:49
【问题描述】:
我目前正在编写一个 WPF 应用程序,它注册一个 url 方案,该方案基本上将命令行参数传递给应用程序。现在的想法是只启动应用程序一次,如果单击附加链接,第一个启动的应用程序应该评估命令行。
由于我从来没有用 Mutex 做到这一点,我已经阅读了一些教程,现在我已经使用 Mutex 和 MemoryMappedFile 添加到我的 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