2012-01-03 15 views
4

高性能なアプリケーションを開発しているため、メインプロセスが一時的に応答を停止し、クラッシュすることがあります。そのアプリケーションは、単に迷惑である、フリーズ、自体を終了することはありません)アプリケーションが応答を停止し、それを強制終了して再起動すると検出する

私は、Appが凍結されたときに、文法的に検出プロへのクリーンな方法を歓迎するので、私は自動的に強制終了するBAT(または他の)を使用することができますプロセスと再起動。

もちろん、これはアプリケーションの監査中の一時的な修正ですが、その間に非常に便利です。

TieBreaker:ところで、ウィンドウの例外画面を上書きして、アプリケーションを終了する方法はありますか? これはたいていの場合、ほとんど迷惑な機能です。

EDIT:GOD'S SAKE FOR
:アプリ BG労働者と、スレッド内のすべての単一のタスクの実行関わらず、凍結おかしくIS!私はコメントでそれを指定しました。カモン、私はそんなに馬鹿じゃない。あなたのアプリがBGの労働者を動かすだけで決して凍ることはありません!そして私が言ったように、ちょうど私の質問に答えてください、私はすでに私のアプリケーションを設計する方法のレッスンを探していないと私は何をすべきか知っています。何度も指定されているように、私はその間にサーバー上の修正を必要としています。 ありがとうございます。

+1

をdoes-別のフォームアプリを作る場合、私はそれを言うでしょうか?奇妙な解決策のように聞こえる。あなたのアプリは何を凍結しているのですか? –

+2

バンデイアの回避策は、永続的なくぼみになるという厄介な癖があります:-) – paxdiablo

+0

あなたは、どこに爆発しているのかを知っているコードの例を投稿できますか? – MethodMan

答えて

1

すべてのCPUの集中的なタスクをGUIから移動し、guiに戻ってステータスを報告します。

メインアプリは決してを凍らせるべきではありません。私は500スレッド以上(一度にすべて)のスレッドを生成し、それらを非同期的に(.net 2)処理して複数のデータベース呼び出しを処理するアプリケーションを作成しました。すべてのプロセスをスレッドセーフな状況に体系的に移行し、直接のGUIコールをすべて削除する必要があると私は考えています。すべての共有データ位置に初めから行われたスマートロックの

  1. 使用法:

    補遺は、どのように私は500 +のスレッドを実行しました。私のブログの記事

    Smart Resource Locking in C# .Net for Thread Safe Code
    C# MultiThreading Using ThreadPool, Anonymous Delegates and Locks

  2. データとアクションの操作を指定した作成したインターフェイス、プロパティなどのエラーステータスを参照してください。
  3. スレッド操作を作成、開始、およびクリーンアップしたスレッドベースクラス(#4および#5のクラス用)が作成されました。 ビジネスロジックはありません。ただ1つの場所でスレッドを処理する方法です。
  4. #2のインターフェイスに基づいて作成され、ステップ3から派生したクラス。データを取得し、データを配置する(ローカライズされたロックを介してスレッドセーフである)ためには、インタフェース経由のクラスが必要であり、そのステータスを報告する必要がありました。 クラスはまた、busy.Sleep(0)によって実行される作業がない場合、スレッドサイクルを諦めるように設計されています。
  5. マネージャクラスが作成されました(独自のスレッドで実行され、#3から派生しました).1-N#4クラスを起動しました。これらのインスタンスはそれぞれ作業リストに入れられました。
  6. マネージャクラスは、作業が完了したと報告されたインスタンスの作業リストを閲覧しただけで、完了した作業にインスタンスを移動しました。また、マネージャクラスは、公開されたプロパティ(子インスタンスによって報告されたすべてのエラーと同様)に対するステータス(ロックによるスレッドセーフ)の記録を保持していました。マネージャは、毎回の実行後にスレッドサイクルを諦め、再び開始する前に250ミリ秒間スリープ状態になりました。
  7. GUIスレッドには、マネージャから特定のステータスを取得するためのタイマーがありました。マネージャのプロパティからデータを抽出し、GUIを呼び出してすべてのステータスとエラーを報告したコントロール(グリッドビュー)をターゲットにします。

こうすることで、個々のスレッドが特定の作業を行うことができました。プロセスが問題に遭遇した場合、それが報告されたか、成功または失敗が報告されました。これらのメッセージは、GUIまで泡立つタイマーまでバブリングしたマネージャーに泡立ちました。 guiはmananagerとtimerを開始する以外はビジネスロジックを処理しませんでした。


私はこれが今の自分の状況を解決しないと、私はあなたの痛みを感じることを取得します。しかし、GUIからビジネスロジックを分離し、スレッド(バックグラウンドワーカー)のエラー状況を処理してGUIにバブルアップするまでは、現在のコードでこの不満が残ります。

ビジネスロジックがGUI操作と密接に結びついていて、GUIから必要なパフォーマンスを得るには、離婚する必要があるというものがロックされている場合。

HTH

+1

メインスレッドは、どのようにステータスを把握していましたか?非常に多くのスレッドでも非常に頻繁に報告されているので、依然としてGUIスレッドで作業が行われることになります。 –

+0

編集 –

+0

を参照してください@エイディパズ:ありがとう、少なくとも私は理解されています。 –

1

私たちは、メインサービスexeファイルは、子スレッドを起動するシェルよりも少し多くなることによってサービスでこれを取り扱います。

子スレッドは、「見た」最後の日時を記録できるときはいつでも、親スレッドに戻って報告する責任があります。

定期的に、サービスアプリケーションは子プロセスのリストをチェックし、所定の時間(すなわち2分)は見られないが、終了したと報告しなかった場合、親プロセスは最初にスレッドに参加して正常にシャットダウンしようとします(通常は失敗します)。それがうまくいかなかった場合、スレッドは異常終了します。

私たちは、OCRソフトウェアのバグのために、実行中のOCRサービスが常時停止していたときから、このアプローチを長年にわたって成功させてきました。

+0

それはスマートです。私はこれを指定しなかったが、これは私のアプリで今行われている方法とまったく同じです。しかし、私はまだアプリの完全なフリーズを追跡したいと思っていました(つまり、「本当に」と「直接」が何らかの形でボンネットから離れたことを検出します)。しかし、これが可能かどうかわかりません –

+0

スレッドを殺すと、殺されたスレッドがヒープロックを保持しているなど、アプリケーションのハングアップを含むあらゆる種類の問題が発生する可能性があります。 (これはOPのオリジナルの問題だったのだろうか?) –

9

他に誰もが:)代わりにバックグラウンドスレッドを使用しないのはなぜ

  Process[] prs = Process.GetProcesses(); 

      foreach (Process pr in prs) 
      { 
       if (!pr.Responding) 
       { 
        try 
        { 
         pr.Kill(); 
        } 
        catch { } 
       } 
      } 

      //then to restart- 
      var process = new Process 
      { 
       StartInfo = new ProcessStartInfo 
       { 
        FileName = @"C:\yourapp.exe" 
       } 
      }; 
      process.Start(); 
明らかに単純化

..

+0

シンプルでエレガント。いいえ、エレガントではありませんが効果的です - それが私たちが必要とするものです。 – CLS

関連する問題