我也很无语,也不想这个么干,只是.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....