using System; using System.Runtime.InteropServices; using System.Threading; #if !V10 && !V11 using Microsoft.Win32.SafeHandles; #endif namespace HongliangSoft.Utilities { ///名前つきのAutoResetEventです。 public class NamedAutoResetEvent : WaitHandle { [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)] private static extern IntPtr CreateEvent(IntPtr security, bool isManualReset, bool initialState, string name); [DllImport("kernel32.dll")] private static extern void SetLastError(int errorCode); [DllImport("kernel32.dll")] private static extern bool SetEvent(IntPtr handle); [DllImport("kernel32.dll")] private static extern bool ResetEvent(IntPtr handle); /// ///初期状態、イベント名を指定してNamedAutoResetEventのインスタンスを作成します。 /// ///初期状態をシグナル状態にする場合はtrue。 ///イベントの名前。 ///制御が返されるとき、イベントオブジェクトが新しく作成された場合にtrueが格納されます。すでに同名のイベントオブジェクトが存在していた場合はfalseが格納されます。 public NamedAutoResetEvent(bool initialState, string name, out bool createdNew) { const int alreadyExists = 0xB7; IntPtr handle = CreateEvent(IntPtr.Zero, false, initialState, name); int error = Marshal.GetLastWin32Error(); if (handle == IntPtr.Zero) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } //.NET 2.0ではMicrosoft.Win32.SafeWaitHandleを使うようになった。 #if !V10 && !V11 base.SafeWaitHandle = new SafeWaitHandle(handle, true); #else base.Handle = handle; #endif createdNew = !(error == alreadyExists); } /// ///イベントの状態をシグナル状態に設定します。 /// ///成功した場合はtrue。 public bool Set() { #if !V10 && !V11 return SetEvent(base.SafeWaitHandle.DangerousGetHandle()); #else return SetEvent(base.Handle); #endif } /// ///イベントの状態を非シグナル状態にします。 /// ///成功した場合はtrue。 public bool Reset() { #if !V10 && !V11 return ResetEvent(base.SafeWaitHandle.DangerousGetHandle()); #else return ResetEvent(base.Handle); #endif } } }