GlobalResetEvent(全局重置事件)是由我编写的一种类似与.NET线程处理方面
的AutoResetEvent(自动重置事件)、ManualResetEvent(手动重置事件)的函数集合
ARE && MRE在.NET中被规范用于线程处理方面,不过在底层它是对系统EVENT
内核对象一个函数封装集合,C++开发者在学习线程时有所涉及、
全局域于Mutex(互斥体)、亦称互斥锁 它同属于.NET线程处理方面与lock关键字
功能相对类似、
由于代码规范使然,GRE 与 ARE && MRE一致依赖于抽象WaitHandle
允许线程通过发送信号相互通信,通常此方式涉及线程需独占访问资源
调用WaitHandle::WaitOne等待信号,内部调用WaitForSingleObject
函数等待内核对象、"生生繁华于枯荑 萋萋空翠自灵犀"
如果WaitHandle处于非终止状态则该线程阻塞,并等待所控制资源的
线程,通过调用WaitHandle::Set / SetEvent发出可用信号
可以通过将一个布尔值传递给构造函数来控制GRE && ARE && MRE
的初始状态,如果初始状态为终止状态,则为 true;否则为 false
调用WaitHandle::Reset / ResetEvent后终止状态被重置为 false,
WaitHandle::Set后终止状态设置为 true
上述两图是利用GRE判断进程是否运行的一个列子,如果没有在系统内检查相关词
条的事件运行MainForm否则WebForm,MainForm在触发OnLoad函数后创建GRE对象
此处与ARE && MRE相似、用于线程处理方面,不过你可以理解封装的代码是
ARE方式,当然也可以修改为MRE方式、
CreateEvent第二参数bManualReset为一个布尔值,如果 true 使用MRE方式否
则 false 使用ARE方式
示例代码:
public static class Program
{
private static GlobalResetEvent greUnk = new GlobalResetEvent("gre_unk", false);
[STAThread]
public static void Main()
{
ThreadPool.QueueUserWorkItem(delegate
{
Thread.Sleep(1200);
Console.WriteLine("test.");
greUnk.Set();
});
greUnk.WaitOne();
Console.WriteLine("ok.");
Console.ReadKey(false);
}
}
GRE代码:
#pragma warning disable 0618
namespace Themyth_Chrome.Thread
{
using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
using System.Threading;
public partial class GlobalResetEvent : WaitHandle, IDisposable
{
private abstract partial class NativeMethod
{
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr OpenEvent(uint dwDesiredAccess, bool bInheritHandle, string lpName);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateEvent(int lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetEvent(IntPtr hEvent);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ResetEvent(IntPtr hEvent);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
public const int WAIT_OBJECT_0 = 0;
public const int NULL = 0;
public const int INFINITE = -1;
public const int EVENT_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | (SYNCHRONIZE | 3));
public const int STANDARD_RIGHTS_REQUIRED = 983040;
public const int SYNCHRONIZE = 1048576;
}
}
public partial class GlobalResetEvent
{
public override void Close()
{
this.SafeWaitHandle.Dispose();
NativeMethod.CloseHandle(Handle);
}
public bool Set()
{
return NativeMethod.SetEvent(Handle);
}
public bool Reset()
{
return NativeMethod.ResetEvent(Handle);
}
public override bool WaitOne()
{
return this.WaitOne(NativeMethod.INFINITE);
}
public override bool WaitOne(int millisecondsTimeout)
{
return NativeMethod.WaitForSingleObject(Handle, millisecondsTimeout) == NativeMethod.WAIT_OBJECT_0;
}
}
public partial class GlobalResetEvent
{
public GlobalResetEvent(IntPtr eventHandle)
{
if (eventHandle == IntPtr.Zero)
throw new Exception("event handle is invalid.");
this.Handle = eventHandle;
this.SafeWaitHandle = new SafeWaitHandle(eventHandle, true);
}
public GlobalResetEvent(string name, bool initialState)
{
if ((this.Handle = NativeMethod.CreateEvent(NativeMethod.NULL, false, initialState, name)) == IntPtr.Zero)
throw new Exception("create event failed.");
this.SafeWaitHandle = new SafeWaitHandle(Handle, true);
}
public static GlobalResetEvent Open(string name)
{
IntPtr hUnkEvent = NativeMethod.OpenEvent(NativeMethod.EVENT_ALL_ACCESS, false, name);
if (hUnkEvent == IntPtr.Zero)
throw new Exception("open event failed.");
return new GlobalResetEvent(hUnkEvent);
}
public static bool OpenExisting(string name)
{
IntPtr hUnkEvent = NativeMethod.OpenEvent(NativeMethod.EVENT_ALL_ACCESS, false, name);
return hUnkEvent != IntPtr.Zero;
}
public static GlobalResetEvent Create(IntPtr eventHandle)
{
return new GlobalResetEvent(eventHandle);
}
public static GlobalResetEvent Create(string name, bool initialState)
{
return new GlobalResetEvent(name, initialState);
}
}
}