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
}
}
}