F.G.
F.G.

Reputation: 19

c# Exception thrown in a thread is caught in an other thread

I read in this post (http://bytes.com/topic/c-sharp/answers/238006-cannot-catch-exception-thread#post970280) that: 'Thrown exceptions are stack-bound objects. Since every thread has its own stack, an exception thrown in thread A cannot suddenly appear in thread B'

But I have a project in which exactly this seems to happen. i am kind of desperate to find the source of my problem. what i am doing is calling 10 threads, of which each one runs several tools simultaneously. each tool is run in yet another thread by starting an executable in a process. this means if i have e.g. 2 tools i will have 10x2 threads in total. the problem is the following: if an exception is thrown, e.g. when one of the tool threads fails and i want to catch it inside the same thread, it happens that any of the threads catches the exception. I verify that by letting the run method output by letting the runTool function include the threadId and toolId in the exception that it throws and comparing the output from the throw and the catch

here the simplified code:

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;
}
}

I'd be grateful for any help

EDIT:

in more detail, the problem shows up when an IOException is thrown. i let every tool create a directory and files in it based on the thread number. if a file is not accessible it will lead to a message like this:

Exception caught in Thread 1, Tool 0: System.IO.FileNotFoundException: Die Datei "C:\tmpdir\3\log.txt" konnte nicht gefunden werden.

which means the exception actuall happened in thread 3, but was caught in thread 1

Upvotes: 1

Views: 315

Answers (1)

Remo Gloor
Remo Gloor

Reputation: 32725

Check if your Tool is threadsafe. If it is not this can lead to your problem.

Upvotes: 3

Related Questions