2011-03-29 22 views
1

私は複数の独立したプロセスを開始するプロジェクトに取り組んでいます。予期せず失敗した場合、他の人たちが影響を受けることなく継続するという点まで、私は彼らを孤立させたい。私はAppDomainsを使ってこれをテストするためにPOC(以下にペースト)を試みましたが、それでも親アプリケーション全体がクラッシュします。マルチスレッド未処理例外

私は間違ったアプローチをしていますか?もしそうなら、私は何をしていますか?そうでない場合、私は何を間違っているのですか?

class Program 
{ 
    static void Main(string[] args) 
    { 
     Random rand = new Random(); 
     Thread[] threads = new Thread[15]; 
     for (int i = 0; i < 15; i++) 
     { 
      AppDomain domain = AppDomain.CreateDomain("Test" + i); 
      domain.UnhandledException += new UnhandledExceptionEventHandler(domain_UnhandledException); 
      domain. 
      Test test = domain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, "ConsoleApplication1.Test") as Test; 
      Thread thread = new Thread(new ParameterizedThreadStart(test.DoSomeStuff)); 
      thread.Start(rand.Next()); 
      Console.WriteLine(String.Format("Thread #{0} has started", i)); 
      threads[i] = thread; 
     } 

     for (int i = 0; i < 15; i++) 
     { 
      threads[i].Join(); 
      Console.WriteLine(String.Format("Thread #{0} has finished", i)); 
     } 
     Console.ReadLine(); 
    } 

    static void domain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Console.WriteLine("UNHANDLED"); 
    } 


} 

public class Test : MarshalByRefObject 
{ 
    public void DoSomeStuff(object state) 
    { 
     int loops = (int)state; 
     for (int i = 0; i < loops; i++) 
     { 
      if (i % 300 == 0) 
      { 
       // WILL break 
       Console.WriteLine("Breaking"); 
       int val = i/(i % 300); 
      } 
     } 
    } 
} 

EDIT

"テスト" クラスは非常に単純化されていることに注意してください。実際のインプリメンテーションは非常に複雑で、例外処理に非常に大きなギャップがあります。

答えて

0

例外をキャッチしたスレッドで例外をキャッチする必要があります。回避策はありません。次に行う必要があるのはおそらく、例外をプライマリappdomainにシリアル化してそれを認識しているからです。結局のところ、それは何か仕事を完了させるために糸を降ろし、その仕事は完了しなかった。それについて何かすべきです。

エミュレートするのは、SQL ServerとASP.NETが動作する方法です。彼らは非常に素晴らしい実行モデルを持っています。クライアントマシンから作業を実行する要求を受け入れます。その要求が爆発した場合、彼らは「申し訳ありません、それはうまくいかない」メッセージを返送する贅沢を持っています。そしてそれは起こらなかったようにそれを肩をすくめて、appdomainsによってうまくサポートされています。

これを処理するためにクライアントマシンに任せます。まれに人間の助けを必要としないbtw。簡単なピーズですが、それはそうした方法で設計された事故ではありませんでした。この実行モデルを本当にエミュレートするには、悲惨さに対処するために他の人を見つける必要もあります。それは難しい。

4

別個のAppDomainsは必要ありません。あなたが行う必要があるのは、TestクラスのメンバーDoSomeStuffで例外をキャッチすることだけです。したがって、これらのスレッドの1つが独自の例外を処理する場合、残りのアプリケーションは引き続き実行できます。

+0

私の編集をご覧ください。この場合のTestクラスはオーバーライドされています。例外処理にはギャップがある可能性が非常に高いため、結果的に私が解決しようとしている状況が発生します。 – Benny

+0

エラー/例外処理に隙間がありません。堅牢なアプリケーションには間に合わないでしょう。また、より厳密なエラー/例外処理を行うと、リソースの使用を制御するのに役立ちます。あなたはスレッドが頻繁に死ぬことを望まない、あなたはあらゆる種類のリソースリークを取得し、プロセス自体が不安定になるでしょう。 –