2011-03-29 112 views
1

我正在開發一個將啓動多個獨立進程的項目。我希望他們被隔離,以至於如果一個人意外失敗,其他人會繼續工作而不受影響。我嘗試過使用AppDomain測試這個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); 
      } 
     } 
    } 
} 

編輯

請注意, 「測試」 類極度簡化。實際的實現會非常複雜,並且在異常處理中可能存在很大的差距。

回答

0

你必須在引發它的線程中捕捉異常,這是沒有辦法的。接下來需要做的事情可能是將異常序列化回主AppDomain,以便知道它。畢竟,它引發了線索,完成了某種工作,而且這項工作還沒有完成。對此應該做些什麼。

你在模擬的是SQL Server和ASP.NET的工作方式。他們有一個非常好的執行模式。他們接受來自客戶機執行工作的請求。如果該請求遭到炸彈襲擊,他們有回報「抱歉,沒有工作」的消息的奢侈。並且像它從未發生過一樣擺脫它,所以很好地支持appdomains。

將它留給客戶機來處理。不經常需要人類順便一提的幫助。容易鬆動,但這不是他們設計的事故。真正模擬這種執行模式還需要找到其他人來處理這種痛苦。這很困難。

4

您不需要單獨的AppDomains。您需要做的只是在Test類的DoSomeStuff成員中捕獲異常。因此,如果其中一個線程處理它自己的異常,那麼其他應用程序可以繼續運行。

+0

請參閱我的編輯。這種情況下的Test類過於簡化。異常處理很可能會有差距,這反過來會導致我正在努力解決的情況。 – Benny 2011-03-29 20:05:36

+0

我會爲_not_拍攝錯誤/異常處理方面的空白,這將使一個強大的應用程序,但它聽起來像它會有一些成本。此外,更嚴格的錯誤/異常處理將幫助您控制資源使用情況。你不希望線程頻繁死亡,你會得到各種資源泄漏,然後進程本身會變得不穩定。 – 2011-03-29 20:44:54