4

在 thread.Abort() 之后会发生什么?

说我有:

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() 被调用时会发生什么?我的 catch 会起作用并继续调用 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

但我确实对此有把握。我不是吗??

4

3 回答 3

7

文档

当调用 Abort 方法来销毁线程时,公共语言运行时会引发 ThreadAbortException。 ThreadAbortException 是一个可以被捕获的特殊异常,但它会在 catch 块结束时自动再次引发。引发此异常时,运行时会在结束线程之前执行所有 finally 块。因为线程可以在 finally 块中进行无限计算或调用 Thread.ResetAbort 来取消中止,所以不能保证线程将永远结束。如果要等到中止的线程结束,可以调用 Thread.Join 方法。Join 是一个阻塞调用,直到线程真正停止执行才返回。

所以换句话说,在你的 catch 块ThreadAbortException执行之后,异常被重新引发,所以你的最后一个记录器行(例如Logger.d(TAG, "run() - ended"))永远不会执行。但是由于调用this.doSoemthing是在 的 catch 块中ThreadAbortException,所以它将执行。

另请注意,您的finally确实执行(请参阅上面的文档)。

于 2012-05-11T20:37:15.783 回答
1

如果您在代码中使用某些地方, response.redirect();那么它将在内部运行thread.abort(); ,因此会引发异常。您可以使用 Response.Redirect(url,false);

于 2015-01-20T11:33:38.157 回答
0

您收到 ThreadAbortException 是因为您的上下文在线程完成运行之前退出。在退出之前,您需要等待线程完成。如果您想退出,您需要确保您的线程可以接收到您的程序希望结束的信号(并对其采取行动),然后您的管理程序执行的代码必须等待线程完成:

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

如果您担心线程永远不会退出,请使用带超时的重载,如果您点击计时器,则明确终止线程。

于 2012-05-11T21:22:20.343 回答