Можете ли вы сбросить исключение .NET в другом потоке? - PullRequest
9 голосов
/ 20 августа 2009

Является ли законным и безопасным в C # перехватывать исключение в одном потоке, а затем повторно выдавать его в другом.

например. это законно

Exception localEx = null;

Thread mythread = new Thread() { () =>
                   {
                        try
                        {
                            DoSomeStuff();
                        }
                        catch(Exception ex)
                        {
                            localEx = ex;
                        }
                    });

myThread.Start();
...
myThread.Join();

if(localEx != null)
   throw localEx;    // rethrow on the main thread

Я думаю, что это законно, но у меня проблемы с поиском любого документа, который это доказывает. Самое близкое, что я нашел, было краткое упоминание о передаче исключений между потоками здесь: http://msdn.microsoft.com/en-us/library/ms229005.aspx

Ответы [ 6 ]

11 голосов
/ 20 августа 2009

Да, это законно. Исключением являются (вообще говоря) описательные объекты без привязки к потоку.

Вы бы лучше заключили исключение вашего потока в новое исключение:

throw new Exception("Something descriptive here", localEx);

Таким образом, трассировка стека в localEx будет сохранена (как InnerException нового исключения).

3 голосов
/ 20 августа 2009

Абсолютно. System.AggregateException добавлено в .NET 4 специально для этой цели во время параллельных операций.

3 голосов
/ 20 августа 2009

То, что вы делаете, не является броском. Это новый выброс экземпляра исключения, который вы случайно обнаружили в переменной. Даже если бы вы использовали только один поток, это было бы плохой идеей, так как исключение выглядит так, как будто оно пришло с сайта "throw". С несколькими потоками я понятия не имею, как кто-нибудь узнает, что было изменение потока.

2 голосов
/ 20 августа 2009

Это законно, и это не перебрасывание, это новое исключение, которое выдается в другом потоке (с тем же объектом исключения)

2 голосов
/ 20 августа 2009

Я не понимаю, почему это не сработает, но вы должны помнить, что вы на самом деле не выбрасываете исключение. Вы генерируете новое исключение, которое просто оказывается тем же объектом исключения. Так, например, трассировка стека скажет, что она была выброшена из «throw localEx;» вместо того, откуда исходное исключение.

0 голосов
/ 20 августа 2009

Я не знаю, почему вы думаете, что это не законно. Если бы это было недопустимо, компилятор наверняка перехватил бы или среда выполнения выдала бы исключение. На самом деле я использую этот шаблон. @John В приложении Windows Forms, которое вызывает веб-сервисы, используя фоновый поток, я использую этот способ. Затем исключение обрабатывается в обработчике верхнего уровня Application.ThreadException, регистрируется и т. Д. Нет необходимости знать, в каком потоке произошло исключение.

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