起動時にいくつかの WCF サービスを開いて 8000 ポートでリッスンする Windows サービスがあります。このサービスが時々クラッシュすることがあります。その場合、TCP 接続は解放されないため、サービスを再度開始しようとすると、サービスが例外をスローします。
AddressAlreadyInUseException: IP エンドポイント 0.0.0.0:8000 にリスナーが既に存在します
いくつかの観察:
CurrPortsまたはを実行する
netstat -ano
と、8000 ポートがまだ使用中 (状態) であり、サービス プロセス ID に対応するLISTENING
プロセス ID によって所有されていることがわかります。XXX
しかし、私のサービスは既にクラッシュしており、タスク マネージャーに表示されなくなりました。したがって、プロセスを強制終了してポートを解放することはできません! もちろん、実行すると次のようtaskkill /PID XXX
に返されます。エラー: プロセス "XXX" が見つかりません。
CurrPortsまたはを実行
netstat -b
すると、リッスン ポートの作成に関与するプロセス名がSystem
であり、MyService.exe
(MyService.exe
サービスが実行されているときは) ではないことがわかります。CurrPortsを使用して接続を閉じようとしましたが、常に次のエラー メッセージが表示されます。
1 つ以上の TCP 接続を閉じることができませんでした。TCP 接続を閉じるには、このツールを管理者として実行する必要があることに注意してください。
(言うまでもなく、CurrPorts を管理者として実行しています...)
TCPViewもあまり役に立ちません。8000 ポートに関連付けられているプロセス名は
<non-existent>
であり、「プロセスの終了」または「接続の終了」を実行しても効果はありません。Process Explorer
XXX
を使用して PID に関連付けられた子プロセスがないかどうかを確認しようとしましたが、ここではうまくいきませんでした。サービスを適切に (クラッシュする前に) 閉じると、TCP 接続が正しく解放されます。
OnStop()
サービスのイベントでWCF サービス ホストを閉じるため、これは正常です。
接続を解放するために私が見つけた唯一の方法は、サーバーを再起動することです (ご想像のとおり、これは運用環境では便利ではありません)。待機しても役に立ちません。TCP 接続は決して解放されません。
Windows サーバーを再起動せずに接続を閉じるにはどうすればよいですか?
PS:私のものと非常によく似た質問がいくつか見つかりました。