簡體   English   中英

在線程C#中拋出異常

[英]throw an Exception in thread C#

我有線程這樣,在我看到示例鏈接文本后

ThreadStart _threadStart = new ThreadStart(delegate()
{
       try
       {
           threadFunction(httpContext);
       }
       catch (Exception ex)
       {
           throw ex;
       }
 });
 Thread _thread = new Thread(_threadStart);
  _thread.Start();

當異常發生時,它不會在啟動它的線程中重新拋出。 那么我做錯了什么或怎么做?

注意:感謝所有高級評論

拋出異常,但這只會結束線程。 在啟動它的線程中不會重新拋出異常。

我認為問題的核心是要理解線程中發生的異常不會傳遞給調用線程進行處理。

例如,假設您有反叛方法:

private static void RebelWithoutACause()
{
    throw new NullReferenceException("Can't touch this!");
}

假設您創建了一個在程序中調用此方法的新線程,並且作為一個安全的程序員,您決定將該工作包含在try/catch塊中:

private static void Main(string[] args)
{
    try
    {
        var thread = new Thread(RebelWithoutACause);
        thread.Start();
        thread.Join();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

但是,如果你在調試器中運行它,你會發現你永遠不會進入catch塊,而是線程將被殺死,調試器會抱怨你有一個未處理的異常。

您需要選擇如何處理異常,但需要在每個線程入口方法中進行處理。 典型處理包括記錄詳細信息,通過UI通知用戶,以及盡可能優雅地關閉應用程序。

你確定拋出了異常嗎? 如果線程因異常而失敗,整個應用程序將崩潰,您可以注意到使用AppDomain.CurrentDomain.UnhandledException事件(請注意,在事件觸發時,您無法阻止您的應用程序結束,但可以清除 -增加資源並保存關鍵數據 - 有關更多信息,請參閱事件文檔。

但是,引用您提到的主題中接受的答案

任何引發頂級異常的線程都表明存在很大問題。

您應該嘗試記錄異常,和/或發信號通知該線程失敗的其他線程。

拋出異常,除了我猜你沒有看到它,因為它被拋出在另一個線程上。 因此,UI線程(或任何線程調用其他線程)無法捕獲異常,因為它沒有看到它。

例如,如果您將異常記錄到文件中,我相信您會看到它。 :)

也許做這樣的事情:

   const int numThreads = 8;
   Thread[] threads = new Thread[numThreads];
   Exception[] threadsExceptions = new Exception[numThreads];
   for (int i = 0; i < numThreads; i++) {
       threadsExceptions[i] = null;
       int closureVariableValue = i;
       ThreadStart command = () =>
       {
           try
           {
               throw new ArgumentException("thread_" + closureVariableValue + "'s exception");
           }catch(Exception any)
           {
               threadsExceptions[closureVariableValue] = any;
           }
       };
       threads[i] = new Thread(command);
       threads[i].Start();
   }
   for(int i = 0; i < numThreads; i++)
   {
       threads[i].Join();
       if (threadsExceptions[i] != null)
       {
           throw threadsExceptions[i];
       }
   }

我想也許你應該看看使用BackgroundWorker類。 您可以訂閱RunWorkerCompleted事件,它具有將包含您的異常的Error屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM