C#傳遞參數(shù)到線程的方法匯總
本文匯總整理了傳遞參數(shù)到線程的方法供大家參考,非常實用,具體內(nèi)容如下:
首先我們要知道什么是線程,什么時候要用到線程,如何去使用線程,如何更好的利用線程來完成工作。
線程是程序可執(zhí)行片段的最小單元,是組成運行時程序的基本單元,一個進程有至少一個線程組成。一般在并行處理等待事件的時候要用到線程,如等待網(wǎng)絡(luò)響應(yīng),等待I/O通訊,后臺事務(wù)處理等情況。使用線程其實很簡單,在.net框架下面你首先要定義一個函數(shù)來完成一些工作,然后實例化一個線程對象Thread thrd = new Thread(new ThreadStart(線程函數(shù))); 其中ThreadStart是一個不帶參數(shù)的函數(shù)委托。最后使用thrd.Start()就可以啟動線程了。當(dāng)然這只是一個很簡單的例子,實際中使用線程會有很多的問題要解決,比如傳遞參數(shù)到線程中,等待線程返回,如何同步線程進行同一資源訪問,如何防止死鎖和競爭條件,如何有效的利用線程池,如何提供線程效率等問題。本文在這里將只對傳遞參數(shù)到線程進行探討。
在上面舉例中我們看到線程實例化的參數(shù)是一個不帶任何參數(shù)的函數(shù)委托,那么就證明了我們不可能通過這樣一個委托傳遞參數(shù)到線程內(nèi)部。那么我們該怎么做呢?
就我目前所知有三種方法可以實現(xiàn):1. 利用線程實現(xiàn)類,將調(diào)用參數(shù)定義成屬性的方式來操作線程參數(shù);2. 利用ParameterizedThreadStart委托來傳遞輸入?yún)?shù);3. 利用線程池來實現(xiàn)參數(shù)傳入。
下面分別加以敘述:
1. 創(chuàng)建線程實現(xiàn)類,這種方式有個最大的優(yōu)點就是可以通過線程返回多個返回值
假設(shè)存在在一個打印功能的線程,通過主函數(shù)傳入打印的行,列和字符數(shù)據(jù),并返回打印的字符總數(shù)。
具體代碼如下:
class ThreadOutput { int _rowCount = 0; int _colCount = 0; char _char = '*'; int _ret = 0; /**//// <summary> /// 輸入?yún)?shù) /// </summary> public int RowCount { set { _rowCount = value; } } public int ColCount { set { _colCount = value; } } public char Character { set { _char = value; } } /**//// <summary> /// 輸出參數(shù) /// </summary> public int RetVal { get { return _ret; } } public void Output() { for (int row = 0; row < _rowCount; row++) { for (int col = 0; col < _colCount; col++) { Console.Write("{0} ", _char); _ret++; } Console.Write("\n"); } } ThreadOutput to1 = new ThreadOutput(); to1.RowCount = 10; to1.ColCount = 20; Thread thrd = new Thread(new ThreadStart(to1.Output)); // 設(shè)置為后臺線程,主要是為不影響主線程的結(jié)束 thrd.IsBackground = true; thrd.Start();
最后要注意的是由于線程實現(xiàn)類是通過屬性來傳遞數(shù)值的,那么在屬性訪問器中要進行線程同步,否則取得的值可能不正確。
2. 利用ParameterizedThreadStart委托來傳遞輸入?yún)?shù)
ParameterizedThreadStart委托是.Net2.0中才有的。該委托提供來在啟動線程時傳遞一個object參數(shù)到線程中。這種方式使用起來比較簡單,但是由于需要對object對象進行類型轉(zhuǎn)換,所以存在類型不一致的隱患。
3. 利用線程池來實現(xiàn)參數(shù)傳入
什么是線程池,線程池是系統(tǒng)提供一個存放線程的容器,進入線程池后的線程控制權(quán)由系統(tǒng)掌握。利用線程池的好處是我們無需為線程存在大量空閑時間而去思考干點別的什么,適合于常規(guī)性的事務(wù)處理。在.Net中線程池是一個static類,所以我們需要通過ThreadPool來調(diào)用相關(guān)的函數(shù)。其中向線程池中加入線程的函數(shù)就是ThreadPool.QueueUserWorkItem(new WaitCallBack(), object obj)。這個函數(shù)有個WaitCallBack的委托,[ComVisibleAttribute(true)]
public delegate void WaitCallback(Object state)
通過這個委托我們也可以傳遞參數(shù)到線程中。
其實還有一種方法可以傳遞參數(shù)到線程中,那就是通過回調(diào)函數(shù)來實現(xiàn),只不過這種方法本質(zhì)上和第一種通過類的數(shù)據(jù)成員來傳遞參數(shù)的機制一樣。所以就不再細(xì)說來!
具體的實現(xiàn)可以參考下面的源代碼:
全部源代碼如下:(該程序在vs 2005編譯通過)
using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace UsingThread { struct RowCol { public int row; public int col; }; class ThreadOutput { // 建立等待時間 static public ManualResetEvent prompt = new ManualResetEvent(false); int _rowCount = 0; int _colCount = 0; char _char = '*'; int _ret = 0; /**//// <summary> /// 輸入?yún)?shù) /// </summary> public int RowCount { set { _rowCount = value; } } public int ColCount { set { _colCount = value; } } public char Character { set { _char = value; } } /**//// <summary> /// 輸出參數(shù) /// </summary> public int RetVal { get { return _ret; } } public void Output() { for (int row = 0; row < _rowCount; row++) { for (int col = 0; col < _colCount; col++) { Console.Write("{0} ", _char); _ret++; } Console.Write("\n"); } // 激活事件 prompt.Set(); } public void Output(Object rc) { RowCol rowCol = (RowCol)rc; for (int i = 0; i < rowCol.row; i++) { for (int j = 0; j < rowCol.col; j++) Console.Write("{0} ", _char); Console.Write("\n"); } } } class Program { static void Main(string[] args) { ThreadOutput to1 = new ThreadOutput(); to1.RowCount = 10; to1.ColCount = 20; Thread thrd = new Thread(new ThreadStart(to1.Output)); // 設(shè)置為后臺線程,主要是為不影響主線程的結(jié)束 thrd.IsBackground = true; thrd.Start(); // 建立事件等待 ThreadOutput.prompt.WaitOne(); Console.WriteLine("{0}", to1.RetVal); ThreadOutput to2 = new ThreadOutput(); to2.RowCount = 5; to2.ColCount = 18; to2.Character = '^'; Thread thrds = new Thread(new ThreadStart(to2.Output)); thrds.IsBackground = true; thrds.Start(); thrds.Join(); Console.WriteLine("{0}", to2.RetVal); // 傳遞參數(shù)給線程的另一種實現(xiàn) RowCol rc = new RowCol(); rc.row = 12; rc.col = 13; to1.Character = '@'; if (ThreadPool.QueueUserWorkItem(new WaitCallback(to1.Output), rc)) Console.WriteLine("Insert Pool is success!"); else Console.WriteLine("Insert Pool is failed!"); Thread.Sleep(1000); // 使用新的ThreadStart委托來傳遞參數(shù) rc.col = 19; to2.Character = '#'; Thread thrdt = new Thread(new ParameterizedThreadStart(to2.Output)); thrdt.Start(rc); thrdt.Join(); } } }
- 深入解析C#中的命名實參和可選實參
- 一道關(guān)于C#參數(shù)傳遞的面試題分析
- C#實現(xiàn)向函數(shù)傳遞不定參數(shù)的方法
- C#中的多線程多參數(shù)傳遞詳解
- c#線程間傳遞參數(shù)詳解
- C#和asp.net中鏈接數(shù)據(jù)庫中參數(shù)的幾種傳遞方法實例代碼
- C# 運用params修飾符來實現(xiàn)變長參數(shù)傳遞的方法
- c#方法中調(diào)用參數(shù)的值傳遞方式和引用傳遞方式以及ref與out的區(qū)別深入解析
- C#難點逐個擊破(1):ref參數(shù)傳遞
- asp.net(C#)函數(shù)對象參數(shù)傳遞的問題
- C# 使用匿名函數(shù)解決EventHandler參數(shù)傳遞的難題
- 理解C#中參數(shù)的值和引用以及傳遞結(jié)構(gòu)和類引用的區(qū)別
相關(guān)文章
C#開發(fā)微信門戶及應(yīng)用(2) 微信消息處理和應(yīng)答
文章主要為大家詳細(xì)介紹了C#開發(fā)微信門戶及應(yīng)用第二篇,微信消息處理和應(yīng)答,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06c# 利用易福門振動模塊VSE002采集振動數(shù)據(jù)的方法
這篇文章主要介紹了c# 利用易福門振動模塊VSE002采集振動數(shù)據(jù)的方法,本文通過圖文實例相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04C#實現(xiàn)百分比轉(zhuǎn)小數(shù)的方法
這篇文章主要介紹了C#實現(xiàn)百分比轉(zhuǎn)小數(shù)的方法,涉及C#進行數(shù)值計算的相關(guān)技巧,需要的朋友可以參考下2015-06-06Unity?UGUI的MaskableGraphic可遮罩圖形組件介紹使用
這篇文章主要為大家介紹了Unity?UGUI的MaskableGraphic可遮罩圖形組件介紹使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07