C # ThreadPool QueueUserWorkItem Обработка исключений - PullRequest
7 голосов
/ 07 марта 2011

Всякий раз, когда поток в моем ThreadPool генерирует исключение, мой код, кажется, застревает в блоке catch внутри функции потока.Как получить исключение обратно в основной поток?

Ответы [ 2 ]

6 голосов
/ 07 марта 2011

Лучше всего, чтобы фоновые потоки не генерировали исключения. Пусть они обрабатывают свои исключения самостоятельно.

В идеале вы должны обернуть код в вашем методе, который выполняется в потоке, в блок try-catch и обработать исключение в блоке catch. Не выбрасывайте его из блока захвата.

Прочтите это для более подробной информации. http://www.albahari.com/threading/#_Exception_Handling

Если вы хотите обновить пользовательский интерфейс из фонового потока, вы можете сделать это, используя Control.InvokeRequired свойство и Control.Invoke метод. Для получения подробной информации и примеров см. Ссылки MSDN.

4 голосов
/ 07 марта 2011

Невозможно перенести исключение из потока в другой. Что вы можете сделать, это создать некоторый механизм синхронизации для передачи информации об исключениях между потоками, а затем создать новое исключение из целевого потока, например:

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

Если у вас есть приложение Win form, все гораздо проще. В предложении catch вашего потока используйте метод Invoke (или BeginInvoke) вашей формы, предоставив в нем детали исключения. В методе, запущенном с Invoke, вы можете перебрасывать или обрабатывать свое исключение так, как хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...