コードでブロッキング メソッドを処理するスレッドを作成します。このようにして、私のコードはそのブロッキング メソッドを実行する以外に他のことを行うことができます。
質問: スレッドを適切に終了するにはどうすればよいですか? ブロッキング メソッドのブロックを解除してから、スレッドを終了する必要がありますか。または、醜いクラッシュを心配せずにスレッドを終了できますか?
コードでブロッキング メソッドを処理するスレッドを作成します。このようにして、私のコードはそのブロッキング メソッドを実行する以外に他のことを行うことができます。
質問: スレッドを適切に終了するにはどうすればよいですか? ブロッキング メソッドのブロックを解除してから、スレッドを終了する必要がありますか。または、醜いクラッシュを心配せずにスレッドを終了できますか?
いくつかのオプションがあります。アプリケーションがダウンしているときに操作が完了するかどうかを気にしない場合は、QueueUserWorkItemを介してThreadPoolスレッドを使用する か、(Servyがコメントで示唆しているように)スレッドのIsBackgroundプロパティをtrueに設定すると、プロセスが可能になります。スレッドを終了せずに終了します。
操作の完了を気にしている場合や、シャットダウン時に実行する必要のあるクリーンアップロジックがある場合は、少なくともgoto戦略としてではなく、Thread.Abortを実際には使用したくないでしょう。私が使用しているのはこれに似たものです:
public abstract class DisposableThread : IDisposable
{
private ManualResetEvent exiting = new ManualResetEvent(false);
private Thread theThread;
private TimeSpan abortTimeout;
public DisposableThread():
this(TimeSpan.FromMilliseconds(100))
{
}
public DisposableThread(TimeSpan abortTimeout)
{
this.abortTimeout = abortTimeout;
theThread = new Thread((_) => ThreadProc());
}
protected virtual void ThreadProc()
{
while(!exiting.WaitOne(0))
{
WorkUnit(exiting);
}
ThreadCleanup();
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
exiting.Set();
if (!theThread.Join(abortTimeout))
{
// logme -- the thread didn't shutdown gracefully
theThread.Abort();
while (!theThread.Join(1000))
{
// logme -- the thread is doing something dumb in an exception handler
}
}
exiting.Dispose();
}
// WorkUnit should return as quickly as safe if the exiting handle is set
// If it doesn't the thread will be aborted if it takes longer than abortTimeout
protected abstract void WorkUnit(WaitHandle exiting);
// override if you need to cleanup on exit
protected virtual void ThreadCleanup() { }
}
これにより、スレッドは正常に終了する機会が与えられ、正常に終了できなかった場合にのみ中止されます。
OK、私の答えが見つかりました。スレッドを参照できるように、スレッドを宣言する必要があります。次に、ネストされたスレッド (HandleClientComm() を持つ) を最初に終了し、次に TCP_Client (null でない場合) と TCP_Listener を閉じます。次に、ListenThread() を終了します。また、ここで言及されている TCP_Listener.Pending() メソッドTcpListener を停止する適切な方法を実装する必要があります。
コールしyourthread.Abort()
ます。リソースとロックが解放されなかったときにすべてが壊れる原因となる昔のようではありませんが、今ではこれにより、通常の方法で処理できる非常に優れた例外が発生します...
http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx
「通常の方法」と言うと、スレッドアボート例外が自動再発生するようです (非常に良いトリックです)。
http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx
しかし、それはあなたが潅水であり、catch ブロックで別の大きなことを開始することを止めることはありません...