C#傳遞參數(shù)到線程的方法匯總
本文匯總整理了傳遞參數(shù)到線程的方法供大家參考,非常實(shí)用,具體內(nèi)容如下:
首先我們要知道什么是線程,什么時(shí)候要用到線程,如何去使用線程,如何更好的利用線程來完成工作。
線程是程序可執(zhí)行片段的最小單元,是組成運(yùn)行時(shí)程序的基本單元,一個(gè)進(jìn)程有至少一個(gè)線程組成。一般在并行處理等待事件的時(shí)候要用到線程,如等待網(wǎng)絡(luò)響應(yīng),等待I/O通訊,后臺(tái)事務(wù)處理等情況。使用線程其實(shí)很簡單,在.net框架下面你首先要定義一個(gè)函數(shù)來完成一些工作,然后實(shí)例化一個(gè)線程對(duì)象Thread thrd = new Thread(new ThreadStart(線程函數(shù))); 其中ThreadStart是一個(gè)不帶參數(shù)的函數(shù)委托。最后使用thrd.Start()就可以啟動(dòng)線程了。當(dāng)然這只是一個(gè)很簡單的例子,實(shí)際中使用線程會(huì)有很多的問題要解決,比如傳遞參數(shù)到線程中,等待線程返回,如何同步線程進(jìn)行同一資源訪問,如何防止死鎖和競爭條件,如何有效的利用線程池,如何提供線程效率等問題。本文在這里將只對(duì)傳遞參數(shù)到線程進(jìn)行探討。
在上面舉例中我們看到線程實(shí)例化的參數(shù)是一個(gè)不帶任何參數(shù)的函數(shù)委托,那么就證明了我們不可能通過這樣一個(gè)委托傳遞參數(shù)到線程內(nèi)部。那么我們?cè)撛趺醋瞿兀?/p>
就我目前所知有三種方法可以實(shí)現(xiàn):1. 利用線程實(shí)現(xiàn)類,將調(diào)用參數(shù)定義成屬性的方式來操作線程參數(shù);2. 利用ParameterizedThreadStart委托來傳遞輸入?yún)?shù);3. 利用線程池來實(shí)現(xiàn)參數(shù)傳入。
下面分別加以敘述:
1. 創(chuàng)建線程實(shí)現(xiàn)類,這種方式有個(gè)最大的優(yōu)點(diǎn)就是可以通過線程返回多個(gè)返回值
假設(shè)存在在一個(gè)打印功能的線程,通過主函數(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è)置為后臺(tái)線程,主要是為不影響主線程的結(jié)束
thrd.IsBackground = true;
thrd.Start();
最后要注意的是由于線程實(shí)現(xiàn)類是通過屬性來傳遞數(shù)值的,那么在屬性訪問器中要進(jìn)行線程同步,否則取得的值可能不正確。
2. 利用ParameterizedThreadStart委托來傳遞輸入?yún)?shù)
ParameterizedThreadStart委托是.Net2.0中才有的。該委托提供來在啟動(dòng)線程時(shí)傳遞一個(gè)object參數(shù)到線程中。這種方式使用起來比較簡單,但是由于需要對(duì)object對(duì)象進(jìn)行類型轉(zhuǎn)換,所以存在類型不一致的隱患。
3. 利用線程池來實(shí)現(xiàn)參數(shù)傳入
什么是線程池,線程池是系統(tǒng)提供一個(gè)存放線程的容器,進(jìn)入線程池后的線程控制權(quán)由系統(tǒng)掌握。利用線程池的好處是我們無需為線程存在大量空閑時(shí)間而去思考干點(diǎn)別的什么,適合于常規(guī)性的事務(wù)處理。在.Net中線程池是一個(gè)static類,所以我們需要通過ThreadPool來調(diào)用相關(guān)的函數(shù)。其中向線程池中加入線程的函數(shù)就是ThreadPool.QueueUserWorkItem(new WaitCallBack(), object obj)。這個(gè)函數(shù)有個(gè)WaitCallBack的委托,[ComVisibleAttribute(true)]
public delegate void WaitCallback(Object state)
通過這個(gè)委托我們也可以傳遞參數(shù)到線程中。
其實(shí)還有一種方法可以傳遞參數(shù)到線程中,那就是通過回調(diào)函數(shù)來實(shí)現(xiàn),只不過這種方法本質(zhì)上和第一種通過類的數(shù)據(jù)成員來傳遞參數(shù)的機(jī)制一樣。所以就不再細(xì)說來!
具體的實(shí)現(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
{
// 建立等待時(shí)間
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è)置為后臺(tái)線程,主要是為不影響主線程的結(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ù)給線程的另一種實(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#中的命名實(shí)參和可選實(shí)參
- 一道關(guān)于C#參數(shù)傳遞的面試題分析
- C#實(shí)現(xiàn)向函數(shù)傳遞不定參數(shù)的方法
- C#中的多線程多參數(shù)傳遞詳解
- c#線程間傳遞參數(shù)詳解
- C#和asp.net中鏈接數(shù)據(jù)庫中參數(shù)的幾種傳遞方法實(shí)例代碼
- C# 運(yùn)用params修飾符來實(shí)現(xiàn)變長參數(shù)傳遞的方法
- c#方法中調(diào)用參數(shù)的值傳遞方式和引用傳遞方式以及ref與out的區(qū)別深入解析
- C#難點(diǎn)逐個(gè)擊破(1):ref參數(shù)傳遞
- asp.net(C#)函數(shù)對(duì)象參數(shù)傳遞的問題
- C# 使用匿名函數(shù)解決EventHandler參數(shù)傳遞的難題
- 理解C#中參數(shù)的值和引用以及傳遞結(jié)構(gòu)和類引用的區(qū)別
相關(guān)文章
C#實(shí)現(xiàn)對(duì)數(shù)組進(jìn)行隨機(jī)排序類實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)對(duì)數(shù)組進(jìn)行隨機(jī)排序類,實(shí)例分析了C#數(shù)組與隨機(jī)數(shù)操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03
Unity實(shí)現(xiàn)單機(jī)游戲每日簽到系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)單機(jī)游戲每日簽到系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04
C#中AutoResetEvent控制線程用法小結(jié)
本文主要來自一道面試題,由于之前對(duì)AutoResetEvent的概念比較模糊,面試題題目很簡潔:兩個(gè)線程交替打印0~100的奇偶數(shù),你可以先動(dòng)手試試,我主要是嘗試在一個(gè)方法里面完成這個(gè)任務(wù),需要的朋友可以參考下2022-07-07
C#實(shí)現(xiàn)撲克游戲(21點(diǎn))的示例代碼
21點(diǎn)又名黑杰克,該游戲由2到6個(gè)人玩,使用除大小王之外的52張牌,游戲者的目標(biāo)是使手中的牌的點(diǎn)數(shù)之和不超過21點(diǎn)且盡量大。本文將用C#實(shí)現(xiàn)這一經(jīng)典游戲,需要的可以參考一下2022-08-08
Unity Shader實(shí)現(xiàn)水波紋效果
這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)水波紋效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
C# WinForms存儲(chǔ)過程操作數(shù)據(jù)庫的實(shí)例講解
這篇文章主要介紹了C# WinForms存儲(chǔ)過程操作數(shù)據(jù)庫的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
C#實(shí)現(xiàn)Excel動(dòng)態(tài)生成PivotTable
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)Excel動(dòng)態(tài)生成PivotTable的相關(guān)方法,感興趣的小伙伴們可以參考一下2016-04-04

