編集:これは難点のように思われるので、邪魔にならないようにします:
これを同期には使用していません。長時間実行されるタスクが不要になった/望ましくなくなったときに単純に強制終了します。
仮説的には、これらのスレッドが単純にコンソールに書き込み (「スレッド 1」など)、ランダムな長さだけスリープしてから終了すると仮定します。それらが中止された場合は、別のコンソール書き込みで通知してもらいたいです (たとえば、「スレッド 1 が中止されました」)。また、通常の機能を実行する可能性がなく、実行前に中止しようとした場合に、中止コードに直接ジャンプできるようにしたいと考えています。通常の機能中に中止された場合、もちろん両方を出力します。
Visual Studio 2008 で .NET 2.0 を実行している ASP サイトで、順番に実行したいスレッドのチャンクがあり (どれだけ重要かはわかりませんが、問題はあります)、それらのスレッドにはクリーンアップ コードが中止されている可能性があります。これは、タスクの進行状況に関係なく実行する必要があります。そこで、次のようなスレッドを立てます。
Thread t = new Thread(delegate() {
try {
/* do things */
System.Diagnostics.Debug.WriteLine("try");
}
catch (ThreadAbortException) {
/* cleanup */
System.Diagnostics.Debug.WriteLine("catch");
}
});
ここで、一連のスレッドを途中で中止したい場合でも、後でクリーンアップを行うことが望ましい場合があります。MSDN を見ると、開始されていないスレッドを .Abort() してから .Start() できることがわかります。この時点で例外を受け取り、正常に実行されます。または、中断されたスレッドを .Join() して、中断が完了するのを待つことができます。おそらく、それらを組み合わせることができます。
http://msdn.microsoft.com/en-us/library/ty8d3wta(v=VS.80).aspx
スレッドが中止されるまで待機するには、Abort メソッドを呼び出した後にスレッドで Join メソッドを呼び出すことができますが、待機が終了する保証はありません。
開始されていないスレッドで Abort が呼び出された場合、そのスレッドは Start が呼び出されたときに中止されます。ブロックされているスレッドまたはスリープしているスレッドで Abort が呼び出されると、スレッドは中断されてから中止されます。
ここで、このコードをデバッグしてステップ実行すると、次のようになります。
t.Abort(); // ThreadState == Unstarted | AbortRequested
t.Start(); // throws ThreadStartException: "Thread failed to start."
// so I comment it out, and
t.Join(); // throws ThreadStateException: "Thread has not been started."
出力がまったく表示されず、try または catch ブロックのブレークポイントにも到達しません。
奇妙なことに、ThreadStartException は .Start() の可能なスローとしてリストされていません。ここから: http://msdn.microsoft.com/en-us/library/a9fyxz7d(v=VS.80).aspx (またはその他のバージョン) )
これは、スレッドがクリーンアップ コードにジャンプする必要があるかどうかを示す start パラメーターを使用し、Abort 呼び出しを前に行うことで回避できることを理解しています (これはおそらく私が行うことです)。そして、スレッドを .Start() してから .Abort() することができました。しかし、.Start と .Abort の間に不確定な時間が経過する可能性があるため、信頼性が低いと考えており、ドキュメントには、私の元の方法が機能するはずであると書かれているようです。
何か不足していますか?ドキュメントは間違っていますか?
編集:ああ。また、パラメーター化されていない Thread(Start) で .Start(param) を呼び出すことはできません。試行錯誤以外に、スレッドがパラメータ化されているかどうかを確認する方法はありますか? プライベート m_Delegate が表示されますが、パブリックはありません...