用内核对象进行线程同步
参考《Windows核心编程系列》谈谈用内核对象进行线程同步,
参考http://blog.csdn.net/shenzi/article/details/4609954
参考http://www.pinvoke.net/default.aspx/kernel32.openevent
一.创建事件
TCCASychronizedHandle = CreateEvent(0, True, False, "TCCASychronized")
二.重置事件
ResetEvent(TCCASychronizedHandle)
三.触发事件
SetEvent(TCCASychronizedHandle)
四.打开事件
C# Signature:
[DllImport("Kernel32.dll", SetLastError=true)]
static extern IntPtr OpenEvent(uint dwDesiredAccess, bool bInheritHandle, string lpName);
Tips & Tricks:
Tip 1: Use OpenEvent to open named event and attach it to AutoResetEvent class:
AutoResetEvent are= new AutoResetEvent(false);
are.Close();
GC.ReRegisterForFinalize(are);
are.Handle= handle; // handle from OpenEvent
Sample Code:
// taken from header files
const uint STANDARD_RIGHTS_REQUIRED = 0x000F0000;
const uint SYNCHRONIZE = 0x00100000;
const uint EVENT_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3);
const uint EVENT_MODIFY_STATE = 0x0002 ;
const long ERROR_FILE_NOT_FOUND = 2L;
/// <summary>
/// Security enumeration from:
/// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/synchronization_object_security_and_access_rights.asp
/// </summary>
[Flags]
public enum SyncObjectAccess : uint
{
DELETE = 0x00010000,
READ_CONTROL = 0x00020000,
WRITE_DAC = 0x00040000,
WRITE_OWNER = 0x00080000,
SYNCHRONIZE = 0x00100000,
EVENT_ALL_ACCESS = 0x001F0003,
EVENT_MODIFY_STATE = 0x00000002,
MUTEX_ALL_ACCESS = 0x001F0001,
MUTEX_MODIFY_STATE = 0x00000001,
SEMAPHORE_ALL_ACCESS = 0x001F0003,
SEMAPHORE_MODIFY_STATE = 0x00000002,
TIMER_ALL_ACCESS = 0x001F0003,
TIMER_MODIFY_STATE = 0x00000002,
TIMER_QUERY_STATE = 0x00000001
}
// open event with error handling
IntPtr handle= OpenEvent(EVENT_ALL_ACCESS | EVENT_MODIFY_STATE, false, name);
int le= Marshal.GetLastWin32Error();
if ((handle==IntPtr.Zero) && (le!=0) && (le!=ERROR_FILE_NOT_FOUND))
throw new ApplicationException(string.Format("Error in pinvoked CreateEvent: {0}", le));
5.判断事件是否触发
const UInt32 INFINITE = 0xFFFFFFFF;
const UInt32 WAIT_ABANDONED = 0x00000080;
const UInt32 WAIT_OBJECT_0 = 0x00000000;
const UInt32 WAIT_TIMEOUT = 0x00000102;
[DllImport("kernel32.dll", SetLastError = true)]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
Sample Code:
private void Run()
{
while (bRunning)
{
try
{
if(WaitForSingleObject(ReceivedEvent,INFINITE) == WAIT_OBJECT_0)
{
// Signaled
DoSomething();
}
}
catch(Exception Ex)
{
// An exception occurred
//
trhow(Ex);
}
}
}
UInt32 waitFor;
waitFor = WaitForSingleObject(hMutex, 10000);
if (waitFor == WAIT_TIMEOUT)
throw new ....
else if (waitFor == WAIT_ABANDONED)
{
ReleaseMutex(waitFor);
throw new ....
}
if (waitFor != WAIT_OBJECT_0)
{
throw new Win32Exception("Synchronization Mutex Error.");
}
return 0;
Alternative Managed API:
If you have a System.Diagnostic.Process object (possibly created by Process.Start), call Process.WaitForExit().
If you're waiting on a file system object, look at System.IO.FileSystemWatcher
System.Threading.WaitHandle and derivatives (e.g. AutoResetEvent)
System.Threading.Timeout.Infinite