簡體   English   中英

線程中拋出的C#異常被其他線程捕獲

[英]c# Exception thrown in a thread is caught in an other thread

我在這篇文章(http://bytes.com/topic/c-sharp/answers/238006-cannot-catch-exception-thread#post970280)中讀到:'拋出的異常是堆棧綁定的對象。 由於每個線程都有自己的堆棧,因此線程A中引發的異常不會突然出現在線程B'中

但是我有一個項目確實在其中發生。 我很想找到問題的根源。 我正在做的是調用10個線程,每個線程同時運行多個工具。 通過在進程中啟動可執行文件,可以在另一個線程中運行每個工具。 這意味着如果我有例如2個工具,我總共將有10x2線程。 問題如下:如果引發異常,例如,當工具線程之一發生故障並且我想在同一線程內捕獲該異常時,任何線程都會捕獲該異常。 我通過運行工具讓runTool函數在拋出異常的情況下包括threadId和toolId,並比較throw和catch的輸出,從而使run方法的輸出得到驗證

這里是簡化的代碼:

class Worker
{

private ManualResetEvent[] threadResetEvents;
private ManualResetEvent[][] toolResetEvents;
private Tool[] tools;
public int stopped = false;


public void run(int threadNo)
{
    threadResetEvents = new ManualResetEvent[threadNo];
    toolResetEvents = new ManualResetEvent[threadNo][];
    for (int i = 0; i < threadNo; i++)
    {
        threadResetEvents[i] = new ManualResetEvent(false);
        ThreadPool.QueueUserWorkItem(new WaitCallback(fillDb), (object)i);
    }
    sendToObservers("Filling database...");
    WaitHandle.WaitAll(threadResetEvents);
}

private void fillDb(object obj)
    {
    int threadId = (int)obj;
    while (!stopped)
            {
        toolResetEvents[threadId] = new ManualResetEvent[tools.Length];
        for (int i = 0; i < tools.Length; i++)
        {
            toolResetEvents[threadId][i] = new ManualResetEvent(false);
            ToolInfoObject info = new ToolInfoObject(threadId, i);
            ThreadPool.QueueUserWorkItem(new WaitCallback(runTool), info);
        }
        WaitHandle.WaitAll(toolResetEvents[threadId]);
    }
}

private void runTool(object obj)
{
    ToolInfoObject info = (ToolInfoObject) i;
    int threadId = info.threadId;
    int toolId = info.toolId;
    try
    {
        tools[toolId].runTool(threadId, toolId);
    }
    catch (Exception e)
    {
        Console.WriteLine("Exception caught in Thread " + threadId + ", Tool " + toolId + ": " + e.GetBaseException());
    }
}

}

class ToolInfoObject
{
public int threadId;
public int toolId;

public ToolInfoObject(int thread, int tool)
{
    this.threadId = thread;
    this.toolId = tool;
}
}

我將不勝感激

編輯:

更詳細地講,當拋出IOException時,問題就會出現。 我讓每個工具都根據線程號在其中創建目錄和文件。 如果無法訪問文件,則會導致出現以下消息:

線程1,工具0中捕獲了異常:System.IO.FileNotFoundException:死於Datei“ C:\\ tmpdir \\ 3 \\ log.txt”。

這意味着異常實際發生在線程3中,但被線程1捕獲

檢查您的Tool是否是線程安全的。 如果不是這樣,可能會導致您的問題。

暫無
暫無

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

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