再論C#でのマルチスレッド処理

スレッドが作成後下記の操作ができます。
1、完全無視。Start()をコールしたら、放置する
2、Suspend()をコールして、いったん停止させる。停止したスレッドがどこかで集中管理される。
3、いったん停止したスレッドに対してResume()で再度復活可能。
停止していないスレッドに対してResume()をコールしても影響がないし、同様に停止したスレッドに対してSuspend()しても影響がない。
4、停止が厳しすぎるなら、Sleep()を使ってDelayさせる。但し、Sleep()は現在のスレッドのみ有効する。指定したスレッドのSleep()は不可。
5、IsAlive属性でスレッドの活動状態を確認可能。IsAliveはスレッドが起動し死亡していない場合のみtrueを返す、
いったんThreadStart objectを実行したら、スレッドが死亡する。
About()で直接殺すのも可能。
Join()メソッドで某スレッドが終了するまで現在のスレッドが待ち状態に入る。
例:
Main()スレッドで下記のコードがある。
	T2.Resume();
	T2.Join();
それはMain()スレッドでT2スレッドを再開させ、T2スレッドが終了するまで待つとなる。
もちろん、T2に無限ループがあったら、Main()スレッドも永遠に待つこととなる。
なので、待つ時間の制限をかける。
	T2.Join(100);
スレッドプログラミングの難しいところは、いかにメモリとほかの共有リソース(shared resources)
の健全性(integrity)を保つことである。

実際の運用では並列で独立したスレッドの競争需要(competing demands)下リソースの健全性を保証する必要がある。
その方法の一人はモニター(Monitors)を使うことである。

MonitorクラスのEnter()とExit()でLOCKとUNLOCKを実現している。
スレッドが臨界コードブロック(critical code blocks)へのアクセスが同期される。
例:
Monitor.Enter(this);
try
{
  // TODO
}
finally
{
  Monitor.Exit(this);
}
Enter()は静的(static)メソッドで、コールすると対象オブジェクトがロックされる。
該当オブジェクトがほかのスレッドによって既にロックされた場合、
このスレッドが続かなくて、ブロック(blocks)が発生する。
いったんロックをかけてしまうと、このスレッドがEnter()後のコードに独占アクセス権(exclusive access)を持っている。
Exit()も静的メソッドで、あるオブジェクトに対してEnter()/Exit()のペアがないと、デッドロック(deadlock)が発生する恐れがある。
TryEnter()を使えばブロックが発生しないまたは一定の時間内のみブロックする。その後諦めてfalseを返す。
例:
if ( ! Monitor.TryEnter( obj, maxWait) )
{
  logFailure( fname );
  return;
}
Enter()/Exit()をペアで扱いやすいようにC#はlockキーワードを提供している。
例:
lock( this )
{
  // TODO
}
このコードブロックは前述したMonitor.Enter()に等価する。

ThreadPoolクラスは予め配分したスレッド(Preallicated threads)を管理するクラスである。