C# 跨进程 临界区 互斥 进程锁
namespace System
{
using System.Diagnostics;
using System.Threading;
/// <summary>
/// 跨进程的临界区。
/// </summary>
public sealed class ProcessLocker : IDisposable
{
/// <summary>
/// 使用示例。
/// </summary>
[Conditional("DEBUG")]
public static void Test()
{
using (new ProcessLocker("TestLocker")) // 成功进入跨进程临界区。
{
// 跨进程的临界区。
} // 成功退出跨进程临界区。
}
public ProcessLocker(string name)
{
try
{
this.name = name;
bool createdNew;
// 尝试创建或打开现有的命名Mutex。
this.mutex = new Mutex(true, name, out createdNew);
// 如果Mutex已存在,则尝试获取所有权
if (!createdNew)
{
// 没有获取所有权期间,阻塞
this.IsWaitOne = this.mutex.WaitOne(-1);
}
else
{
// 新创建的Mutex,已拥有所有权
this.IsWaitOne = true;
}
}
catch (AbandonedMutexException)
{
// 前任所有者未释放Mutex,当前线程获得所有权
this.IsWaitOne = true;
}
catch (Exception ex)
{
Trace.WriteLine($"Process locker init {name} exception: " + ex);
}
}
~ProcessLocker()
{
Dispose(false);
}
private readonly string name;
private readonly Mutex mutex;
public bool IsDisposed { get; private set; }
public bool IsWaitOne { get; private set; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!IsDisposed)
{
IsDisposed = true;
if (mutex != null && IsWaitOne)
{
try
{
// 释放Mutex并销毁资源
mutex.ReleaseMutex();
if (disposing)
{
(mutex as IDisposable)?.Dispose();
}
}
catch (Exception ex)
{
Trace.WriteLine($"Process locker dispose {name} exception: " + ex);
}
}
}
}
}
}