簡體   English   中英

重溫 Thread.Abort() - 安全嗎?

[英]Revisiting Thread.Abort() - is it safe?

MSDN 關於遷移遺留多線程應用程序(來自this page on exception handling in threads):

通常,更改將暴露以前無法識別的編程問題,以便可以修復它們。 然而,在某些情況下,程序員可能會利用運行時支持,例如終止線程。 根據情況,他們應該考慮以下遷移策略之一:

重構代碼,使線程在收到信號時優雅地退出。

使用 Thread.Abort 方法中止線程。

如果必須停止線程以便進程終止可以繼續,則使線程成為后台線程,以便在進程退出時自動終止。

在所有情況下,該策略都應遵循例外的設計指南。 請參閱例外設計指南。

這表明使用Thread.Abort是終止線程的合適方法。 在我不看的時候有什么變化嗎? 我聽到的最后一個消息是這可能會導致意外行為,因此不應使用。

Thread.Abort比以前更安全,原因如下。

  • 在非托管代碼中執行時,運行時將推遲中止。
  • 中止將允許finally塊執行。

但是,在注入ThreadAbortException的確切時間仍然存在問題。 考慮這段代碼。

public class Example
{
  private DateTime value = DateTime.MinValue;

  public void DoSomething()
  {
    try
    {
      value = DateTime.UtcNow;
    }
    finally
    {
    }
  }
}

如果此代碼在 32 位平台上運行,則value變量可能會在調用Thread.Abort並且在寫入value的過程中注入ThreadAbortException時損壞。 由於DateTime是 8 個字節,因此必須使用多條指令進行寫入。

可以通過將關鍵代碼放在finally塊中並使用受約束的執行區域來防止這種情況發生,但是除了您定義的最簡單類型之外,要正確處理所有類型是非常困難的。 即使這樣,您也不能將所有內容都放在finally塊中。

一般來說, Thread.Abort會殺死線程,將它們當時正在處理的數據留在未知的 state 中。 state 是未知的,處理這些數據通常是不安全的。 但是,當您嘗試終止一個進程時,您不再期望處理該線程的數據,那么為什么不中止它呢?

好吧,Thread.Abort() 的問題在於它可能會在工作過程中中止線程。 這可能會導致您的 state 損壞。 這就是為什么建議使用 volatile bool 標志來控制線程,並讓線程優雅地完成其任務,但基於該標志。

有關更多詳細信息,我記得這篇博文

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM