C# 多線程之線程式控制制

来源:http://www.cnblogs.com/CUIT-DX037/archive/2017/06/07/6955873.html
-Advertisement-
Play Games

方案一: 調用線程式控制制方法.啟動:Thread.Start();停止:Thread.Abort();暫停:Thread.Suspend();繼續:Thread.Resume(); 線程定義為: 值得註意的是: 通過 Thread.Abort() 停下來的線程(或自行運行結束的線程),都無法直接通過 ...


方案一:

   調用線程式控制制方法.啟動:Thread.Start();停止:Thread.Abort();暫停:Thread.Suspend();繼續:Thread.Resume();

 

        private void btn_Start_Click(object sender, EventArgs e)
        {
            mThread.Start();  // 開始
        }

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            mThread.Abort();  // 終止
        }

        private void btn_Suspend_Click(object sender, EventArgs e)
        {
            mThread.Suspend();  // 暫停
        }

        private void btn_Resume_Click(object sender, EventArgs e)
        {
            mThread.Resume();  // 繼續
        }

線程定義為:

            mThread = new Thread(() =>
            {
                try
                {
                    for (int j = 0; j < 20; j++)
                    {
                        int vSum = 0;
                        this.textBox1.Text += "--->";
                        for (int i = 0; i < 100000000; i++)
                        {
                            if (i % 2 == 0)
                            {
                                vSum += i;
                            }
                            else
                            {
                                vSum -= i;
                            }
                        }
                        this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
                        Thread.Sleep(1000);
                    }
                }
                catch (ThreadAbortException ex)
                {
                    Console.WriteLine("ThreadAbortException:{0}", ex.Message);
                }
            });

值得註意的是: 通過 Thread.Abort() 停下來的線程(或自行運行結束的線程),都無法直接通過 Thread.Start() 方法再次啟動,必須重新創建一個線程啟動。

所以,“開始按鈕”事件應為:

        private void btn_Start_Click(object sender, EventArgs e)
        {
            // 定義線程
            mThread = new Thread(() => // Lambda 表達式
            {
                try
                {
                    for (int j = 0; j < 20; j++)
                    {
                        int vSum = 0;
                        this.textBox1.Text += "--->";
                        for (int i = 0; i < 100000000; i++)
                        {
                            if (i % 2 == 0)
                            {
                                vSum += i;
                            }
                            else
                            {
                                vSum -= i;
                            }
                        }
                        this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
                        Thread.Sleep(1000);
                    }
                }
                catch (ThreadAbortException ex)
                {
                    Console.WriteLine("ThreadAbortException:{0}", ex.Message);
                }
            });

            mThread.Start();  // 開始
        }

此外,對於 Thread.Suspend() 和 Thread.Resume() 方法,微軟已經將其標記為過時:

Thread.Suspend has been deprecated.  Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.  http://go.microsoft.com/fwlink/?linkid=14202(Thread.Suspend 已被否決。請使用系統中的其他類線程,如監視器、互斥體、事件和信號量,以同步線程或保護資源。http://go.microsoft.com/fwlink/?linkid=14202)

因為,無法判斷當前掛起線程時它正在執行什麼代碼。如果在安全許可權評估期間掛起持有鎖的線程,則 AppDoamin 中的其它線程可能被阻止。如果線上程正執行構造函數時掛起它,則 AppDomain 中嘗試使用該類的其它線程將被阻止。這樣容易發生死鎖。

方案二:

   在 線程運行過程中 適當的位置(如某個完整的功能/命令後)判斷是否要繼續線程,再決定線程的命運。

  1.定義一個全局變數:

        int mTdFlag = 0; // 1:正常運行;2:暫停;3:停止

  2. 定義一個判斷方法:

        bool WaitForContinue()
        {
            if (this.mTdFlag == 3)
            {
                return false; // 返回false,線程停止
            }
            else if (this.mTdFlag == 2)
            {
                while (mTdFlag != 1)
                {
                    Thread.Sleep(200); // 假暫停;停頓時間越短,越靈敏
                    if (this.mTdFlag == 3)
                    {
                        return false; // 返回false,線程停止
                    }
                }
            }
            return true; // 返回true,線程繼續
        }

    3.修改 控制命令 事件:

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            this.mTdFlag = 3;
            //mThread.Abort();  // 終止
        }

        private void btn_Suspend_Click(object sender, EventArgs e)
        {
            this.mTdFlag = 2;
            //mThread.Suspend();  // 暫停
        }

        private void btn_Resume_Click(object sender, EventArgs e)
        {
            this.mTdFlag = 1;
            //mThread.Resume();  // 繼續
        }

   4.線上程運行過程中適當的位置,判斷線程是否繼續

            mThread = new Thread(() =>
            {
                try
                {
                    for (int j = 0; j < 20; j++)
                    {
                        int vSum = 0;
                        this.textBox1.Text += "--->";
                        for (int i = 0; i < 100000000; i++)
                        {
                            if (i % 2 == 0)
                            {
                                vSum += i;
                            }
                            else
                            {
                                vSum -= i;
                            }
                            if (i % 10000000 == 0)
                            {
                                this.textBox1.Text += ".";
                            }
                            if (!WaitForContinue()) // 返回 false 則,停止
                            {
                                break;
                                //return;
                            }
                        }
                        this.textBox1.Text += string.Format("{0} => vSum = {1}\r\n", DateTime.Now.ToString(), vSum);
                        if (!WaitForContinue()) // 返回 false 則,停止
                        {
                            break;
                            // return;
                        }
                        Thread.Sleep(1000);
                    }
                }
                catch (ThreadAbortException ex)
                {
                    Console.WriteLine("ThreadAbortException:{0}", ex.Message);
                    this.textBox1.Text += ex.Message + "...";
                }
                finally
                {
                    this.textBox1.Text += "線程已結束";
                }
            });

 

在窗體中,解決跨線程訪問問題:在窗體構造函數中添加代碼:  Control.CheckForIllegalCrossThreadCalls = false;

 

[http://www.cnblogs.com/CUIT-DX037/]


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

-Advertisement-
Play Games
更多相關文章
  • 本人系初學菜鳥,如有大神路過望指點一二,小弟不勝感激!!! 1。配置hosts文件 (路徑:C:\Windows\System32\drivers\etc) 2.IIS管理器添加網站 3.修改預設文檔 4.用管理員打開vs。右鍵項目站點 設置屬性 ...
  • 題目:做一個商場收銀的小程式,可能會出現的情況包括:正常收費,九折優惠,七折優惠,滿300減50等各種不同隨時會變化的優惠活動。 界面如下: 分析: 首先我們對於收錢寫一個父類CashSuper。這個父類是用來包含其他的各種收費方式的:正常收費、七折優惠、八折優惠、九折優惠、滿300減50、滿400 ...
  • 先定義枚舉 上面這個方法根據傳入的枚舉值通過反射獲得display中name的值 ...
  • 廢話不說直接上代碼; using MongoDB.Bson.Serialization.Attributes; namespace XL.Core.MongoDB { public interface IEntity<TKey> { /// <summary> /// 主鍵 /// </summar ...
  • 照著 利用表達式樹構建委托改善反射性能 做了一點小更改正好適合自己用 測試: ...
  • using System;using System.Collections.Generic;using System.Text;using System.Collections;using System.Data.SqlClient;using System.Data;using System.Co ...
  • 1,創建winform窗體應用程式 2,在界面上拖入DataGridView控制項 3,添加相應的列如圖: 4,開始編寫後面的代碼: private DataTable CountryDt = new DataTable(); private DataTable CityDt = new DataTa ...
  • 今天偶然間遇到的問題,搞不清緣由!但還是想記錄下來,點滴的記錄才能更快更好地成長!問題:如圖 IIS伺服器上運行正常,本地IIS運行調試就出現此問題! 經過IIS Express調試一次之後,本地IIS調試又恢復了正常!始終沒整明白到底是啥問題,以前從來沒有遇到過類似的問題!本人系初學菜鳥,如有大神 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...