OSDN Git Service

3a2477f99c9251e4922174ad309034ed6bdbc7a7
[strokestylet/CsWin10Desktop3.git] / FDK24 / 同期 / TriStateEvent.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq;
5 using System.Threading;
6
7 namespace FDK.同期
8 {
9         /// <summary>
10         ///             ON, OFF, 無効 の3状態を持つイベント。
11         /// </summary>
12         /// <remarks>
13         ///             状態が 無効 にされると、ON待ち/OFF待ちスレッドのブロックはいずれも解除され、
14         ///             またそれ以降、状態を変更することはできなくなる(リセットすると戻る)。
15         /// </remarks>
16         public class TriStateEvent
17         {
18                 public enum 状態種別 { ON, OFF, 無効 }
19
20                 public 状態種別 現在の状態
21                 {
22                         get
23                         {
24                                 lock( this._スレッド間同期 )
25                                 {
26                                         return this._状態;
27                                 }
28                         }
29                         set
30                         {
31                                 lock( this._スレッド間同期 )
32                                 {
33                                         if( this._状態 == 状態種別.無効 )
34                                                 return;     // 一度無効になったら、以降は変更不可。
35
36                                         this._状態 = value;
37
38                                         switch( value )
39                                         {
40                                                 case 状態種別.ON:
41                                                         this._無効イベント?.Reset();
42                                                         this._OFFイベント?.Reset();
43                                                         this._ONイベント?.Set();
44                                                         break;
45
46                                                 case 状態種別.OFF:
47                                                         this._無効イベント?.Reset();
48                                                         this._ONイベント?.Reset();
49                                                         this._OFFイベント?.Set();
50                                                         break;
51
52                                                 case 状態種別.無効:
53                                                         this._ONイベント?.Set();
54                                                         this._OFFイベント?.Set();
55                                                         this._無効イベント?.Set();
56                                                         break;
57                                         }
58                                 }
59                         }
60                 }
61
62                 public TriStateEvent( 状態種別 初期状態 = 状態種別.OFF )
63                 {
64                         this.リセットする( 初期状態 );
65                 }
66
67                 /// <summary>
68                 ///             状態が ON または 無効 になるまでブロックする。
69                 /// </summary>
70                 /// <returns>
71                 ///             解除後の状態(ON または 無効)。
72                 ///     </returns>
73                 public 状態種別 ONになるまでブロックする()
74                 {
75                         int h = EventWaitHandle.WaitAny( new EventWaitHandle[] { this._ONイベント, this._無効イベント } );
76                         return ( h == 0 ) ? 状態種別.ON : 状態種別.無効;
77                 }
78                 
79                 /// <summary>
80                 ///             状態が OFF または 無効 になるまでブロックする。
81                 /// </summary>
82                 /// <returns>
83                 ///             解除後の状態(OFF または 無効)。
84                 ///     </returns>
85                 public 状態種別 OFFになるまでブロックする()
86                 {
87                         int h = EventWaitHandle.WaitAny( new EventWaitHandle[] { this._OFFイベント, this._無効イベント } );
88                         return ( h == 0 ) ? 状態種別.OFF : 状態種別.無効;
89                 }
90
91                 /// <summary>
92                 ///             状態が 無効 になるまでブロックする。
93                 /// </summary>
94                 public void 無効になるまでブロックする()
95                 {
96                         this._無効イベント.WaitOne();
97                 }
98
99                 /// <summary>
100                 ///             状態をリセットする。
101                 ///             すでに無効になった後でも可。
102                 /// </summary>
103                 public void リセットする( 状態種別 初期状態 = 状態種別.OFF )
104                 {
105                         lock( this._スレッド間同期 )
106                         {
107                                 this.現在の状態 = 初期状態;
108
109                                 this._無効イベント = new ManualResetEvent( false );
110                                 this._ONイベント = new ManualResetEvent( 初期状態 == 状態種別.ON );
111                                 this._OFFイベント = new ManualResetEvent( 初期状態 == 状態種別.OFF );
112                         }
113                 }
114
115                 private 状態種別 _状態 = 状態種別.OFF;
116                 private ManualResetEvent _無効イベント = null;
117                 private ManualResetEvent _ONイベント = null;
118                 private ManualResetEvent _OFFイベント = null;
119                 private readonly object _スレッド間同期 = new object();
120         }
121 }