28

追放されているスレッドを手に入れました.誰が私のスレッドを殺しているのか、そしてその理由を知りたいです.

スレッドが OS によって強制終了されていることがわかりましたが、これを確認し、可能であればなぜそれが強制終了されているのかを知りたいです。

スレッドに関しては、死ぬ前に少なくとも 40 分の実行があると断言できますが、約 5 分で突然死んでしまいます。

public void RunWorker()
{
    Thread worker = new Thread(delegate()
    {
        try
        {
            DoSomethingForALongLongTime();
        }
        catch(Exception e)
        {
           //Nothing is never logged :(
           LogException(e);
           throw e;
        }
    });

    worker.IsBackground = true;
    worker.SetApartmentState(System.Threading.ApartmentState.STA);
    worker.Start();
}

編集:回答への対処

  • Try/Catch 考えられる例外:
    実装されており、何もキャッチしません:(
  • メイン スレッドの停止:
    このスレッドは Web サーバーによって作成され、引き続き実行されます。
  • 作業完了:
    作業は完了していません。最終的にデータベースに影響を与えるため、スレッドが終了したときに作業が完了したかどうかを確認できます。

これらのことを考えた結果、この質問にたどり着きました。誰が私のスレッドを殺しているのですか??

ps。ろうそくの棒を持っているのは、リビングルームにいるゴールデン夫人ではありません:)

4

15 に答える 15

20

さまざまな人 (ここでは私を含む) が、IIS で実行時間の長いスレッドをホストすることは悪い考えだと指摘しました。スレッドは IIS の「ワーカー プロセス」内で実行されます。これらのプロセスは IIS によって定期的に終了 (リサイクル) されるため、スレッドが停止します。

IIS ワーカー プロセスのリサイクルをオフにして、違いが生じるかどうかを確認することをお勧めします。詳細については、こちらをご覧ください。

于 2010-05-12T10:01:04.120 に答える
13

あなたのスレッドはおそらく例外をスローしただけです。try/catch ブロックを配置しDoSomethingForALongLongTimeて、何がピックアップされるかを確認してください。


更新:これを Web サーバーから開始していることに以前は気づきませんでした。それは非常に悪い考えかもしれません。特に、別のスレッドは、から派生した情報を使用していHttpContext.Currentますか? これには、、、RequestなどResponseSessionおよびページからの情報が含まれます。

これらはリクエストが続く間しか続かないため、これは悪いことです。要求が終了すると、控えめに言っても、それらは無効になります。

Web アプリケーションまたは Web サービス内から実行時間の長いスレッドを開始する必要がある場合は、単純な Windows サービスを作成し、その中で WCF サービスをホストする必要があります。Web ページから、タスクを実行するために必要なすべての情報をサービスに送信します。サービスはトランスポートとして MSMQ を使用することもできます。これにより、サービスがビジー状態になった場合でも、メッセージが失われないことが保証されます。

于 2010-04-20T14:28:52.190 に答える
5

詳細情報を取得する方法として考えられるのは、デバッガーをアタッチし、スレッドの終了時に中断することです。スレッドの終了方法によっては、これが機能しない場合があります。

  1. まだ持っていない場合は、Windows 用のデバッグ ツールをダウンロードします。
  2. windbg.exe を実行し、プロセスにアタッチします
  3. windbg にブレークしsxe et、スレッドの終了時にブレークを有効にするように入力します
  4. デバッガーが壊れたら、システムの状態、他のスレッドなどを調べます。
  5. マネージド スタックを取得するには、sos.dll をロードし ( .loadby sos mscorsvr.loadby sos mscorwks、または.loadby sos clr動作するはずです)、実行します!clrstack(!help他の sos コマンドについては を参照してください) 。

他のスレッドの終了から多くのノイズが発生する場合は、気になるスレッド ID でない場合は、windbg をスクリプト化してブレーク後に続行します。

編集:スレッドがプロセス内から終了していると思われる場合は、TerminateThread( bp kernel32!TerminateThread) とExitThread( bp kernel32!ExitThread) にブレークポイントを設定して、キラーのスタックをキャッチすることもできます。

于 2010-05-07T02:14:27.627 に答える
4

答えはわかりませんが、いくつかの考え:

  • 例外をスローしている可能性がありますか?DoSomethingForALongTime() 呼び出しの周りに try/catch を入れてみましたか?
  • 正常に終了するポイントはありますか?それらにいくつかのログを記録してみてください。
  • デバッガーの内外で同じ動作が得られますか? デバッガーの出力ウィンドウにヒントはありますか?

アップデート

あなたが言った:

このスレッドは Web サーバーによって作成され、引き続き実行されます

スレッドが asp.net 内で実行されている場合、asp.net ワーカー プロセスのリサイクル時にスレッドが強制終了されている可能性があります。これは定期的に行われます。ワーカー プロセスのリサイクルをオフにしてみて、違いが生じるかどうかを確認してください。

于 2010-04-20T14:31:58.673 に答える
4

あなたの編集は答えを明らかにします:

バトラーWeb サーバーです。

これらのスレッドをどのように正確にホストしていますか? Web サーバー環境は、長期間存続するプロセスをホストするように正確に設計されているわけではありません。実際、ランナウェイ サイトを 40 分ごとに停止するように構成されている可能性があります。

編集:
迅速な修正のworker.IsBackground = false;ために、現在のtrueの設定により、システムはbgwを待たずに親スレッドを強制終了できるため、設定するのが最善の方法です。

別の注意点として、ASP.NET アプリケーションで BackgroundWorker を使用する意味はほとんどありません。これは、WinForms および WPF を対象としています。一部の Threads プロパティを変更しているため、このために別のスレッドを作成することをお勧めします。これは、ThreadPool (Bgw) スレッドには推奨されません。

于 2010-04-20T14:45:14.533 に答える
3

プロセスが終了している可能性があります。それは何でしょう worker.IsBackground = true; メインスレッドが終了したときにスレッドを強制終了するように設計されています。

于 2010-04-20T14:30:24.683 に答える
3

バックグラウンド スレッドは、フォアグラウンド スレッドが実行されている間だけ実行されます。

すべてのフォアグラウンド スレッドが終了するとすぐに、実行中のバックグラウンド スレッドは中止されます。

于 2010-04-20T14:30:49.277 に答える
2

web.configのconfiguration\system.web \ httpRuntimeexecutionTimeout値を増やすことができます(デフォルト値は.NET 4.0では110秒で、90はhttp://msdn.microsoft.com/en-us/library/に対応します。 e1f13641.aspx)。動的に変更してみることができますServer.ScriptTimeout=300(http://www.beansoftware.com/ASP.NET-Tutorials/Long-Operations.aspxを参照)。このパラメータが役に立たない場合は、IISからのスレッドのリサイクル以外の問題があると思います。このパラメーターのデフォルト値を確認する方法は、スレッドの通常の稼働時間よりもはるかに短くなります。あなたの問題には別の性質があると思いますが、確かに...

なぜスレッドにアパートの状態を設定するのですか?作業スレッドで使用するCOMオブジェクトはどれですか?コードを挿入することもできる、ほとんどの作業を行うアンマネージコードがありますか?SomethingForALongLongTime問題を解決するためには、もっと多くの情報が必要だと思います。

そしてもう1つ少し提案。呼び出し後にコード行を挿入して、例外なく終了しないSomethingForALongLongTime();ことを確認してください。SomethingForALongLongTime

更新:スレッドがIISによって強制終了されないようにするために、SomethingForALongLongTime();スレッドを使用する代わりに強制終了するプロセスを作成してみてください。

于 2010-05-05T23:52:35.947 に答える
2

簡単な答えは次のとおりです。「殺人者は名刺を残しません」;)

  • スレッドが IIS でホストされている場合、おそらくスレッドはリサイクルするアプリ プール プロセスによって強制終了されます。サーバーは引き続き実行される可能性がありますが、アイテムをホストするプロセスは、新しいリクエストがすべてを再開するまで停止します。
  • スレッドが実行可能ファイルでホストされている場合、スレッドを強制終了できる唯一の方法は、自分でスレッドを強制終了するか、スレッドで例外をスローするか、ホスト プロセスを終了することです。

お役に立てれば。

于 2010-04-20T15:28:51.273 に答える
2

RunWorker() を呼び出すと、スレッドへの参照をリストに追加できます。スレッドが停止したことを検出したら、スレッドの状態を調べることができます。おそらく、どのように停止したかがわかります。または、おそらく停止しておらず、何らかのリソース (データベースへの接続など) を待機しているだけです。

List runningThreads = ...
public void RunWorker() {
    Thread worker = new Thread(delegate()
    ..
    runningThreads.add(worker);
    worker.Start();
}

public void checkThreads() {
 for (Thread t : runningThreads) {
   Console.WriteLine("ThreadState: {0}", t.ThreadState);
 }
}
于 2010-05-11T20:12:06.783 に答える
2

例外をチェックしても有用な情報が得られない場合は、スレッド コードを取得して、重要なポイントでログ ファイルに書き込みます。その後、いつ機能しなくなったのか、できればその理由を正確に確認できます。

于 2010-04-20T14:30:28.023 に答える
1

アプリ ドメインの UnhandledException イベントを使用してみてください: http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

いくつかの例外を見逃すと、いくつかの情報が得られる場合があります

于 2010-05-12T10:20:18.860 に答える
1

Stack OverflowOut of Memoryなど、キャッチできないさまざまな例外の 1 つをスローしている可能性があります。これらは、追跡するのが最も難しい例外です。

このスレッドの実行中のメモリ消費量はどのようになりますか? メモリ プロファイラーを使用して、制御不能かどうかを確認できますか? 内部ループにログを追加できますか? 再帰的なメソッドがある場合は、カウンターを追加し、再帰が不可能な回数の場合は例外をスローします。大きなオブジェクト ヒープの断片化を引き起こす可能性のある大きなオブジェクトを使用していますか (実際に外出していなくても、メモリ不足エラーが発生します)。

于 2010-05-06T00:07:19.010 に答える
1

AsyncTasks を使用して、asp.net で長時間実行される作業を達成する

于 2010-05-11T20:14:38.120 に答える
1

DoSomethingForALongTime() に多くのデバッグ ログをインストルメント化する必要があります。これにより、コードの実行が停止する場所を見つけることができます。または、デバッガーをアタッチして、すべての最初のチャンスの例外で中断します。

于 2010-05-07T02:27:06.707 に答える