[WM]封装一个Mutex给.NET CF v2
我也很无语,也不想这个么干,只是.NET CF v2是这也不支持,那也不支持.
前段时间要做一个只让程序启动一次的东西,进入我大脑的第一个词汇就是互斥量(信号量的特殊化). 网上搜了一下确实也有人用互斥量实现我的那个需求.
动手做起来才发现不太对劲,.NET CF v2 的互斥量是不支持命名的,没名字就不能用于IPC(进程间通讯),那还有毛用......
翻了翻MSDN,写了一个Mutex,还挺好用,其实就那么几个API :
NativeMethod
sealed class NativeMethod
{
public const UInt32 WAIT_OBJECT_0 = 0x00000000;
public const UInt32 WAIT_TIMEOUT = 258;
public const UInt32 WAIT_FAILED = 0xffffffff;
[DllImport("coredll.Dll", SetLastError = true)]
public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, int bInitialOwner, string lpName);
[DllImport("coredll.Dll", SetLastError = true)]
public static extern UInt32 ReleaseMutex(IntPtr hMutex);
//WAIT_OBJECT_0 The state of the specified object is signaled.
//WAIT_TIMEOUT The time-out interval elapsed, and the object's state is nonsignaled.
[DllImport("coredll.Dll", SetLastError = true)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
[DllImport("coredll.Dll", SetLastError = true)]
public static extern UInt32 CloseHandle(IntPtr hObject);
}
{
public const UInt32 WAIT_OBJECT_0 = 0x00000000;
public const UInt32 WAIT_TIMEOUT = 258;
public const UInt32 WAIT_FAILED = 0xffffffff;
[DllImport("coredll.Dll", SetLastError = true)]
public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, int bInitialOwner, string lpName);
[DllImport("coredll.Dll", SetLastError = true)]
public static extern UInt32 ReleaseMutex(IntPtr hMutex);
//WAIT_OBJECT_0 The state of the specified object is signaled.
//WAIT_TIMEOUT The time-out interval elapsed, and the object's state is nonsignaled.
[DllImport("coredll.Dll", SetLastError = true)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
[DllImport("coredll.Dll", SetLastError = true)]
public static extern UInt32 CloseHandle(IntPtr hObject);
}
然后Wrapper一下就行了,无非就是创建一个named Mutex.
Mutex
public sealed class Mutex:IDisposable
{
private IntPtr hMutex;
public Mutex(bool initiallyOwned, string lpName)
{
int bInitialOwner = initiallyOwned ? 1 : 0;
this.hMutex = NativeMethod.CreateMutex(hMutex, bInitialOwner, lpName);
if(this.hMutex==IntPtr.Zero)
{
throw new ApplicationException(string.Format("创建Mutex失败,错误代码{0}", Marshal.GetLastWin32Error()));
}
}
~Mutex()
{
Dispose();
}
public void ReleaseMutex()
{
UInt32 bResult = NativeMethod.ReleaseMutex(this.hMutex);
//Nonzero indicates success.
//Zero indicates failure.
//To get extended error information, call GetLastError.
if (bResult > 0)
return;
throw new ApplicationException("调用线程不拥有互斥体。");
}
public bool WaitOne()
{
return WaitOne(System.Threading.Timeout.Infinite);
}
public bool WaitOne(int dwMilliseconds)
{
UInt32 dwResult = NativeMethod.WaitForSingleObject(this.hMutex, dwMilliseconds);
if (dwResult == NativeMethod.WAIT_FAILED)
throw new ObjectDisposedException("Mutex句柄无效");
if(dwResult==NativeMethod.WAIT_TIMEOUT)
return false;
if(dwResult==NativeMethod.WAIT_OBJECT_0)
return true;
return false;
}
public void Dispose()
{
NativeMethod.CloseHandle(this.hMutex);
GC.SuppressFinalize(this);
}
}
{
private IntPtr hMutex;
public Mutex(bool initiallyOwned, string lpName)
{
int bInitialOwner = initiallyOwned ? 1 : 0;
this.hMutex = NativeMethod.CreateMutex(hMutex, bInitialOwner, lpName);
if(this.hMutex==IntPtr.Zero)
{
throw new ApplicationException(string.Format("创建Mutex失败,错误代码{0}", Marshal.GetLastWin32Error()));
}
}
~Mutex()
{
Dispose();
}
public void ReleaseMutex()
{
UInt32 bResult = NativeMethod.ReleaseMutex(this.hMutex);
//Nonzero indicates success.
//Zero indicates failure.
//To get extended error information, call GetLastError.
if (bResult > 0)
return;
throw new ApplicationException("调用线程不拥有互斥体。");
}
public bool WaitOne()
{
return WaitOne(System.Threading.Timeout.Infinite);
}
public bool WaitOne(int dwMilliseconds)
{
UInt32 dwResult = NativeMethod.WaitForSingleObject(this.hMutex, dwMilliseconds);
if (dwResult == NativeMethod.WAIT_FAILED)
throw new ObjectDisposedException("Mutex句柄无效");
if(dwResult==NativeMethod.WAIT_TIMEOUT)
return false;
if(dwResult==NativeMethod.WAIT_OBJECT_0)
return true;
return false;
}
public void Dispose()
{
NativeMethod.CloseHandle(this.hMutex);
GC.SuppressFinalize(this);
}
}
写的时候参考了:
http://www.cnblogs.com/gakusei/archive/2009/02/21/1395462.html
和MSDN....