2012-05-11 2 views
4

Что происходит после thread.Abort() ??C# thread abort exception

Скажет у меня есть:

Thread mWorker = new Thread(new ThreadStart(this.run)); 
.. 
mWorker.Start(); 

**where** 

private void run() 
{ 
     Logger.d(TAG, "run()"); 

     ... 
     try { 
     while (this.mRunning){ 
      ... 
     } 
     } catch (ThreadAbortException tae){ 
      Logger.e(TAG,"some msg", tae); 
      this.doSomething(); 
     } catch (IOException ioe){ 
      Logger.e(TAG,"some msg", ioe); 
      this.doSomething(); 
     } catch (Exception e){ 
      Logger.e(TAG,"some msg", e); 
      this.doSomething(); 
     } finally { 
      gracefoulyClose(); 
     } 

     Logger.d(TAG, "run() - ended"); 
} 

Нить более сложная .. но отображаются здесь Эссенциальный. Итак, что происходит при вызове Abort()? будет ли моя уловка работать и продолжить вызов doSomething()?

Потому что я до сих пор получить в консоли:

A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll 
An exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll but was not handled in user code 

Но у меня есть улов для этого. Не так ли?

ответ

7

Из doc:

Когда вызов к методу Прервать, чтобы уничтожить нить, общий язык среда бросает ThreadAbortException. ThreadAbortException - особое исключение, которое можно поймать, но оно должно быть снова поднято в конце блока catch. Когда возбуждено это исключение, runtime выполняет все блоки finally перед завершением потока. Поскольку поток может выполнить неограниченное вычисление в блоках finally или вызвать Thread.ResetAbort, чтобы отменить прерывание, нет гарантии, что нить никогда не закончится. Если вы хотите подождать, пока закончится прерванная нить, вы можете вызвать метод Thread.Join . Join - это блокирующий вызов, который не возвращается до , поток фактически прекращает выполнение.

Итак, другими словами, после улова блока для ThreadAbortException выполняет, исключение ререйз, поэтому ваш последний регистратор линии (например, Logger.d(TAG, "run() - ended")) никогда не выполняется. Но так как звонок this.doSoemthing находится в блоке catch для ThreadAbortException, то он выполнит.

Обратите внимание, что ваш finally блок выполняет выполнить (см. Документ выше).

+0

так моя попытка поймать OK? потому что, когда вы используете «try {code A} catch (Ex e) {}" .. вы знаете, что код A может вызвать исключение .. но мой код не бросает поток Abort .. Не знаю, чувствую ли я?мой код собирается поймать AbortExcetion? – pulancheck1988

+0

Если что-то в вашем цикле while вызывает исключение ThreadAbortException, то да, оно будет поймано в вашем блоке catch. ThreadAbortException - особое исключение, которое может быть вызвано временем выполнения .NET, а не обязательно вашим кодом. – dcp

0

Вы получаете исключение ThreadAbortException, потому что ваш контекст выходит до завершения потока. Перед тем, как выйти, вам нужно подождать завершения потока. Если вы хотите выйти, вам нужно убедиться, что ваш поток может получить сигнал (и действовать на него), который ваша программа хочет завершить, а затем ваш код, который управляет выполнением программы, должен ждать завершения потока:

if (mThread != null && mThread.IsAlive) { 
    mThread.Join(); 
} 

Используйте перегрузку с таймаутом, если вы беспокоитесь о том, что нить никогда не выйдет, и явно уничтожьте поток, если вы нажмете на таймер.

+0

Вы проверяете mThread! = Null && mThread.IsAlive в одной строке. Это может привести к нарушению доступа, если mThread имеет значение null. –

+0

Пока нулевая проверка является первым элементом в условном выражении, никакая ошибка не будет выбрана. Это просто пример и не предназначен для всех условий программного обеспечения. Сфокусируйте меньше на педантике и больше на вопросе. –

1

Если вы используете некоторые, где в коде response.redirect(); тогда он будет внутренне запустить thread.abort(); так он будет бросать exception.Instead того, что вы можете использовать Response.Redirect(url,false);

+0

Я получаю 'исключение прерывания потока', когда я использую' Response.End(); ', но если я использую' HttpContext.Current.ApplicationInstance.CompleteRequest(); вместо этого я не получаю исключение, кроме нового исключение «Сервер не может добавлять заголовок после того, как были отправлены заголовки HTTP», любые предложения? – Binny

Смежные вопросы