C#如何实现Mutex指定时间后自动释放供VB.NET应用识别操作
问题根因
- 多余调用
ReleaseMutex方法:ReleaseMutex仅允许当前持有Mutex所有权的线程调用,你创建Mutex时第一个参数initialOwner设为false,代表当前线程不持有Mutex所有权,直接调用ReleaseMutex会抛出同步异常,导致后续的Close/Dispose逻辑没有执行,Mutex句柄泄漏一直存在。 - 你本质是用命名内核对象的存在性做跨进程标识,完全不需要用到Mutex的互斥语义,
ReleaseMutex方法对你的需求完全无用。 - 你之前的推测错误:
System.Windows.Forms.Timer的Tick事件默认运行在UI线程,和创建Mutex的是同一个线程,不存在跨线程调用的问题。
解决方案
直接删除ReleaseMutex调用即可,5秒后直接关闭释放Mutex句柄,当所有进程对该命名Mutex的引用都被释放后,系统会自动销毁该对象,VB端就无法检测到它的存在。
修改后的C#代码
private static Mutex mutex = null; private void button1_Click(object sender, EventArgs e) { try { // 先释放之前可能存在的旧Mutex,避免多次点击泄漏 if (mutex != null) { mutex.Close(); mutex.Dispose(); mutex = null; } Form myForm = (Form)Application.OpenForms["BrowserWindow"]; Core.IsUserClosed = false; myForm.WindowState = FormWindowState.Minimized; myForm.Show(); myForm.WindowState = FormWindowState.Normal; myForm.Focus(); bool createdNew; // 创建命名Mutex,不需要持有所有权 mutex = new Mutex(false, "mymutex", out createdNew); SetTimeout(() => { if (mutex == null) return; // 不需要调用ReleaseMutex,直接关闭释放句柄即可 mutex.Close(); mutex.Dispose(); mutex = null; }, 5000); } catch (Exception exception1) { // 建议此处增加异常日志,方便后续排查问题 return; } } public void SetTimeout(Action action, int timeout) { var timer = new System.Windows.Forms.Timer(); timer.Interval = timeout; timer.Tick += delegate (object sender, EventArgs args) { action(); timer.Stop(); timer.Dispose(); }; timer.Start(); }
可选优化方案(更贴合需求的实现)
如果你只是需要一个跨进程的存在性标识,用EventWaitHandle比Mutex更合适,没有所有权限制,使用逻辑更简洁:
// 声明标识对象 private static EventWaitHandle signal = null; // 创建有效期标识 signal = new EventWaitHandle(false, EventResetMode.ManualReset, "my_signal", out createdNew); // 到期销毁标识 signal.Close(); signal.Dispose();
VB端检测逻辑只需把Mutex.OpenExisting改成EventWaitHandle.OpenExisting即可,其余代码不用修改。
内容的提问来源于stack exchange,提问作者MirrorMirror
相关产品推荐
相关产品推荐

