c#在一个线程中抛出的异常被另一个线程捕获

本文关键字:线程 异常 另一个 一个 | 更新日期: 2023-09-27 18:09:22

我在这篇文章(http://bytes.com/topic/c-sharp/answers/238006-cannot-catch-exception-thread#post970280)中读到:'抛出的异常是堆栈绑定对象。因为每个线程都有它的在线程A中抛出的异常不会突然出现在线程B '

但我有一个项目,这似乎正好发生。我很想找到问题的根源。我正在做的是调用10个线程,其中每个线程同时运行几个工具。通过在进程中启动可执行文件,每个工具都在另一个线程中运行。这意味着如果我有2个工具,我将总共有10x2个线程。问题如下:如果抛出异常,例如当一个工具线程失败,我想在同一线程内捕获它时,任何线程都会捕获异常。我通过让run方法输出(让runTool函数在它抛出的异常中包含threadId和toolId)并比较throw和catch的输出(

)来验证这一点。

这里是简化后的代码:

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: Die Datei "C:'tmpdir'3'log.txt" konnte night gefunden werden.

表示异常实际上发生在线程3中,但是在线程1中被捕获

c#在一个线程中抛出的异常被另一个线程捕获

检查您的Tool是否线程安全。如果不是,这可能会导致您的问题。