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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...