C# Thread.Abort方法真的讓線程停止了嗎?

来源:https://www.cnblogs.com/Liyuting/archive/2018/05/25/9087287.html
-Advertisement-
Play Games

大家都知道在C#裡面,我們可以使用 Thread.Start方法來啟動一個線程,當我們想停止執行的線程時可以使用Thread.Abort方法來強制停止正在執行的線程,但是請註意,你確定調用了Thread.Abort方法後線程就立刻停止了嗎? 答案是:不是! 下麵我們來解釋一下Abort方法是如何工作 ...


大家都知道在C#裡面,我們可以使用 Thread.Start方法來啟動一個線程,當我們想停止執行的線程時可以使用Thread.Abort方法來強制停止正在執行的線程,但是請註意,你確定調用了Thread.Abort方法後線程就立刻停止了嗎? 答案是:不是!

 

下麵我們來解釋一下Abort方法是如何工作的。因為公用語言運行時管理了所有的托管的線程,同樣它能在每個線程內拋出異常。Abort方法能在目標線程中拋出一個ThreadAbortException異常從而導致目標線程的終止。不過Abort方法被調用後,目標線程可能並不是馬上就終止了。因為只要目標線程正在調用非托管的代碼而且還沒有返回的話,該線程就不會立即終止。而如果目標線程在調用非托管的代碼而且陷入了一個死迴圈的話,該目標線程就根本不會終止。不過這種情況只是一些特例,更多的情況是目標線程在調用托管的代碼,一旦Abort被調用那麼該線程就立即終止了。

 

其實一個線程在運行時,我們可以通過Thread.ThreadState屬性讀出它的狀態,正在運行的線程狀態就是ThreadState.Running。然後如果我們想強制停止正在執行的線程,就會調用Thread.Abort方法,但是Thread.Abort方法做的事情只是線上程上拋出了一個ThreadAbortException異常,然後將線程的狀態置為ThreadState.AbortRequested,MSDN對AbortRequested狀態的解釋是:已對線程調用了 Thread.Abort 方法,但線程尚未收到試圖終止它的掛起的System.Threading.ThreadAbortException,也就是說線程在ThreadState.AbortRequested狀態時表示即將結束但是還沒有真正結束。可是Thread.Abort方法將線程的狀態置為ThreadState.AbortRequested後就立馬返回了,而線程真正結束後的狀態應該是ThreadState.Aborted,所以一定要註意在調用了Thread.Abort方法後,要記得迴圈檢查Thread.ThreadState屬性的值或者調用Thread.Join方法來確保被終止線程已經真正停止,只有當Thread.ThreadState屬性為Aborted或Thread.Join方法返回時,才表示線程真正結束了。

 

下麵我就寫一個示例代碼來說明在調用Thread.Abort方法後,怎樣保證線程停止後代碼才會繼續執行

 

var thread = new Thread(
    new ThreadStart(
        () =>
            {
                while (true)
                {
                    //該線程會進行無限迴圈,自己不會結束
                    Thread.Sleep(100);
                }
            }));

thread.IsBackground = true;
thread.Start();//啟動線程

thread.Abort();//調用Thread.Abort方法試圖強制終止thread線程

//上面調用Thread.Abort方法後線程thread不一定馬上就被終止了,所以我們在這裡寫了個迴圈來做檢查,看線程thread是否已經真正停止。其實也可以在這裡使用Thread.Join方法來等待線程thread終止,Thread.Join方法做的事情和我們在這裡寫的迴圈效果是一樣的,都是阻塞主線程直到thread線程終止為止
while (thread.ThreadState!=ThreadState.Aborted)
{
    //當調用Abort方法後,如果thread線程的狀態不為Aborted,主線程就一直在這裡做迴圈,直到thread線程的狀態變為Aborted為止
    Thread.Sleep(100);
}

//當跳出上面的迴圈後就表示我們啟動的線程thread已經完全終止了

 

不過請記住使用Thread.Abort方法來終止正在執行的線程並不是一個好的方法,因為Abort方法是通過線上程上拋異常來終止線程的,這樣可能會產生一些意想不到的問題。最好的辦法是在啟動的線程中加信號燈,當想要終止線程執行時就更改信號燈的狀態,啟動的線程當讀到信號燈狀態改變後自己結束代碼的執行,這才是最安全的做法。

 

 

原文鏈接:https://www.cnblogs.com/OpenCoder/p/4587249.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • #coding:utf-8import random,stringdef GetPassword(length): # 隨機生成數字個數 Ofnum=random.randint(1,length) Ofletter=length-Ofnum # 選中ofnum個數字 slcNum=[random. ...
  • 隱藏圖不是什麼新鮮的東西,具體表現在大部分社交軟體中,預覽圖看到的是一張圖,而點開後看到的又是另一張圖。雖然很早就看到過這類圖片,但是一直沒有仔細研究過它的原理,今天思考了一下,發現挺有趣的,所以自己也寫了個簡單的演算法把兩張圖片合成為一張隱藏圖。 比如下麵這張圖。 當背景顏色為白色時,通常也就是在預 ...
  • 準備工作: 建立.NET Core Web Api項目 新建一個用於Api請求的UserInfo類 2、建立.NET Core Web項目 一、使用jQuery Ajax訪問 (一)、表單 [FromForm] 數據類型:Object ContenyType類型:application/x-www- ...
  • 這是一個ASP.NET Core2.0專題文章列表 ...
  • using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.... ...
  • 根據自己項目的開發需要,整理了一個SqlHelper類 相比較網上通用的SqlHelper類方法主要有一下幾點的不同: 1.因為要操作多個資料庫,所以資料庫連接字元串沒有寫死到方法里,作為參數提供出來。 2.因為涉及到多表多庫的操作,涉及到資料庫級別的事物,以及邏輯業務上的事物,因此,要從最基元的部 ...
  • 警告 載入屬性“OutputPath”失敗。 輸入的路徑不是有效的輸出路徑。 解決方案: 先項目打包備份一下哦,再執行以下操作哦。 1.右鍵項目屬性, 發佈,發佈位置修改成 publish\ 生成 ,輸出路徑修改成 bin\Debug\ 2.打開項目所在的文件夾,找到一個尾碼名 .csproj的文件 ...
  • 之前的ASP.NET網站,只要把*.html、*.css、*.jpg、*.png、*.js等靜態文件放在項目根目錄,預設都可以直接被瀏覽;但ASP.NET Core 小改了瀏覽靜態文件的方式,預設根目錄不再能瀏覽靜態文件,需要指定靜態文件的目錄,才可以被瀏覽。本篇將介紹ASP.NET Core瀏覽靜 ...
一周排行
    -Advertisement-
    Play Games
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...
  • 1. JUnit 最佳實踐指南 原文: https://howtodoinjava.com/best-practices/unit-testing-best-practices-junit-reference-guide/ 我假設您瞭解 JUnit 的基礎知識。 如果您沒有基礎知識,請首先閱讀(已針 ...