baidu

[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); 
        }


 然后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);
        }
    }


写的时候参考了:

http://www.cnblogs.com/gakusei/archive/2009/02/21/1395462.html

和MSDN....

posted @ 2009-12-16 09:30  egmkang  阅读(1298)  评论(4编辑  收藏  举报