5

FTP サーバー間でファイルを移動するファイル転送アプリケーションがあります。いつでも何十ものファイルを移動させることができます。FTP サーバーのフラッディングを防ぐために、モニターおよびセマフォ ロックのシステムを使用しています。

コール スタックに従って、FTP クライアントが System.Net.Sockets.Socket.Receive() 内のどこかでフリーズすることがよくあります。例外が発生しないため、問題に対処できません。FTP クライアントを使用したい他のスレッドをブロックしているため、スレッドをキャンセルしたいと思います。

System.Net.Sockets.Socket.Receive() を最終的に呼び出すメソッドを新しいスレッドで開始し、一定期間後にスレッドを中止することを検討しましたが、スレッドの中止後にソケットが開いたままになることを懸念しています。応答しないスレッドの後に、より適切に強制終了してクリーンアップする方法はありますか?

4

3 に答える 3

4

いいえ。協力なしにスレッドを強制終了する安全で信頼できる方法はありません。存在するメカニズムは非常に手間がかかる可能性があり、および/または必ずしも機能するとは限りません。

  • 他のスレッドを試すこともできますがInterrupt()、それは通常、待機中/スリープ中のスレッド、またはブロックする可能性のある何かを実行しているスレッドにのみ割り込むだけです。それがブロッキングを伴わない何かの真っ只中にある場合、それはそれが再びブロックしようとするまで、割り込みを見ることさえなく、ましてや応答することさえありません。これは、不正なスレッドがある場合、「決して」ない可能性があります。
  • Abort()おそらくスレッドを殺すでしょうが、それも保証されていません-スレッドは頑固に死ぬことを拒否することができます。そして、たとえそれが死んだとしても、それはあなたのアプリドメインを疑わしい状態のままにする可能性があります。(スレッドがfinallyブロックに入ったときに中止されたと仮定します。例外がその場でスローされ、最終的にブロックは実行されません。したがって、解放されるもの(ロック、ネイティブリソースなど)は解放されないままになります。 。)
  • どうやら、アプリドメインをアンロードしても、その中のスレッドが中止されるだけなので、Thread.Abort適用の不確実性があります。さらに、それが機能する場合は、アプリドメイン内のすべてのスレッドも強制終了されます。
  • 比較的安全で確実に機能するのは、プロセス全体を強制終了することだけです。そして、そうすると、外部のものの状態についての保証はありません。保持されているリソースが解放/クローズ/何であれ、特定の状態(たとえば、「中断されていない」など)にあることを保証することはできません。

この場合、より良い解決策は非同期で受信することかもしれません( /ではなく実際の非同期のもの(ReceiveAsync)を使用して)。そうすれば、スレッドはネイティブのものでブロックされず、より簡単に中断できます(何らかの理由でそれを実行する必要がある場合、非同期の利点には、入力を監視するためだけに別のスレッドが必要ないことが含まれます)。BeginReceiveEndReceive

于 2012-08-03T14:58:36.047 に答える
2

ReceiveTimeoutの設定を見たことがありますか?

それ以外の場合は、各スレッドでWatchdogプロパティを設定し、Watchdog変数のステータスを確認して、応答しないスレッドを特定できます。

于 2012-08-03T14:59:01.913 に答える
0

(可能であれば)別のプロセスでスレッドを実行し、容赦なくスレッドを強制終了することをお勧めします。その後、OSはすべてのリソースを解放します

于 2012-08-03T14:54:32.980 に答える