7

Whenever a thread in my ThreadPool throws an exception, my code seems to be stuck at the catch block inside the thread function. How do I get the exception back to the main thread?

Maxim Gueivandov
  • 2,370
  • 1
  • 20
  • 33
Aks
  • 5,188
  • 12
  • 60
  • 101
  • 1
    possible duplicate of [How to catch exceptions from a ThreadPool.QueueUserWorkItem?](http://stackoverflow.com/questions/753841/how-to-catch-exceptions-from-a-threadpool-queueuserworkitem) – Henrik Mar 07 '11 at 09:49
  • Duplicate: http://stackoverflow.com/questions/753841/how-to-catch-exceptions-from-a-threadpool-queueuserworkitem – Nick Mar 07 '11 at 09:47
  • those methods dont work. I get an exception saying `The calling thread must be STA, because many UI components require this. ` – Aks Mar 07 '11 at 09:51
  • Ok, it might be worth posting some code. This sounds like you're possibly accessing a GUI component from a non-GUI thread. – Nick Mar 07 '11 at 09:52
  • I am accessing a listbox to add the exception from the thread. If I throw directly its stuck in the thread catch block, it wont go back to the main thread – Aks Mar 07 '11 at 09:55
  • If you're directly accessing a ListBox from a ThreadPool thread and the ListBox was created on a different thread, you'll need to use the Control.Invoke to ensure you only access the ListBox from the Gui thread which created it. – Nick Mar 07 '11 at 09:58
  • could you show me some sample code? How can I do this? – Aks Mar 07 '11 at 10:00
  • Why don't you edit your question to show what you're trying to do. Then I'll update my answer with some code if required. – Nick Mar 07 '11 at 10:01
  • Does this answer your question? [How to catch exceptions from a ThreadPool.QueueUserWorkItem?](https://stackoverflow.com/questions/753841/how-to-catch-exceptions-from-a-threadpool-queueuserworkitem) – Michael Freidgeim May 10 '21 at 05:52

2 Answers2

7

The best practice is that your background threads should not throw exceptions. Let them handle their exceptions on their own.

Ideally you should wrap the code in your method that executes on a thread in a try-catch block and handle the exception in the catch block. Do not re-throw it from the catch block.

Read this for more details. http://www.albahari.com/threading/#_Exception_Handling

If you want to update the UI from background thread you can do that by using Control.InvokeRequired property and Control.Invoke method. See the MSDN links for details and examples.

Unmesh Kondolikar
  • 9,256
  • 4
  • 38
  • 51
  • But my UI has to display the exception. What can I do? – Aks Mar 07 '11 at 09:56
  • 1
    Catch it in the thread and use a queue (pipe) to send a message back to the UI thread to display the error. Exceptions over thread borders is a bad thing and very hard to trouble shot. – David Mårtensson Mar 07 '11 at 10:04
4

It's not possible to transfer exception from a thread to another one. What can you do is to built some synchronization mechanism to transfer exception information between threads and then throw a new exception from the target thread something like:

class Program
{
    Exception _savedException = null;
    AutoResetEvent _exceptionEvent = new AutoResetEvent(false);

    static void Main(string[] args)
    {
        Program program = new Program();
        program.RunMain();
    }

    void RunMain()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod));

        while (true)
        {
            _exceptionEvent.WaitOne();
            if (_savedException != null)
            {
                throw _savedException;
            }
        }
    }

    void ThreadMethod(object contxt)
    {
        try
        {
            // do something that can throw an exception
        }
        catch (Exception ex)
        {
            _savedException = ex;
            _exceptionEvent.Set();
        }
    }
}

If you have a Win form application things are much simpler. In the catch clause of your thread use Invoke (or BeginInvoke) method of your form, providing it with the exception details. In the method launched with Invoke you can rethrow or treat your exception as you want.

Brent Worden
  • 10,624
  • 7
  • 52
  • 57
Eugene
  • 2,858
  • 1
  • 26
  • 25