欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#傳遞參數(shù)到線程的方法匯總

 更新時(shí)間:2014年08月07日 14:47:43   投稿:shichen2014  
這篇文章主要介紹了C#傳遞參數(shù)到線程的方法,非常實(shí)用,需要的朋友可以參考下

本文匯總整理了傳遞參數(shù)到線程的方法供大家參考,非常實(shí)用,具體內(nèi)容如下:

首先我們要知道什么是線程,什么時(shí)候要用到線程,如何去使用線程,如何更好的利用線程來(lái)完成工作。

線程是程序可執(zhí)行片段的最小單元,是組成運(yùn)行時(shí)程序的基本單元,一個(gè)進(jìn)程有至少一個(gè)線程組成。一般在并行處理等待事件的時(shí)候要用到線程,如等待網(wǎng)絡(luò)響應(yīng),等待I/O通訊,后臺(tái)事務(wù)處理等情況。使用線程其實(shí)很簡(jiǎn)單,在.net框架下面你首先要定義一個(gè)函數(shù)來(lái)完成一些工作,然后實(shí)例化一個(gè)線程對(duì)象Thread thrd = new Thread(new ThreadStart(線程函數(shù))); 其中ThreadStart是一個(gè)不帶參數(shù)的函數(shù)委托。最后使用thrd.Start()就可以啟動(dòng)線程了。當(dāng)然這只是一個(gè)很簡(jiǎn)單的例子,實(shí)際中使用線程會(huì)有很多的問(wèn)題要解決,比如傳遞參數(shù)到線程中,等待線程返回,如何同步線程進(jìn)行同一資源訪問(wèn),如何防止死鎖和競(jìng)爭(zhēng)條件,如何有效的利用線程池,如何提供線程效率等問(wèn)題。本文在這里將只對(duì)傳遞參數(shù)到線程進(jìn)行探討。

在上面舉例中我們看到線程實(shí)例化的參數(shù)是一個(gè)不帶任何參數(shù)的函數(shù)委托,那么就證明了我們不可能通過(guò)這樣一個(gè)委托傳遞參數(shù)到線程內(nèi)部。那么我們?cè)撛趺醋瞿兀?/p>

就我目前所知有三種方法可以實(shí)現(xiàn):1. 利用線程實(shí)現(xiàn)類,將調(diào)用參數(shù)定義成屬性的方式來(lái)操作線程參數(shù);2. 利用ParameterizedThreadStart委托來(lái)傳遞輸入?yún)?shù);3. 利用線程池來(lái)實(shí)現(xiàn)參數(shù)傳入。

下面分別加以敘述:

1. 創(chuàng)建線程實(shí)現(xiàn)類,這種方式有個(gè)最大的優(yōu)點(diǎn)就是可以通過(guò)線程返回多個(gè)返回值
假設(shè)存在在一個(gè)打印功能的線程,通過(guò)主函數(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)類是通過(guò)屬性來(lái)傳遞數(shù)值的,那么在屬性訪問(wèn)器中要進(jìn)行線程同步,否則取得的值可能不正確。

2. 利用ParameterizedThreadStart委托來(lái)傳遞輸入?yún)?shù)

ParameterizedThreadStart委托是.Net2.0中才有的。該委托提供來(lái)在啟動(dòng)線程時(shí)傳遞一個(gè)object參數(shù)到線程中。這種方式使用起來(lái)比較簡(jiǎn)單,但是由于需要對(duì)object對(duì)象進(jìn)行類型轉(zhuǎn)換,所以存在類型不一致的隱患。

3. 利用線程池來(lái)實(shí)現(xiàn)參數(shù)傳入

什么是線程池,線程池是系統(tǒng)提供一個(gè)存放線程的容器,進(jìn)入線程池后的線程控制權(quán)由系統(tǒng)掌握。利用線程池的好處是我們無(wú)需為線程存在大量空閑時(shí)間而去思考干點(diǎn)別的什么,適合于常規(guī)性的事務(wù)處理。在.Net中線程池是一個(gè)static類,所以我們需要通過(guò)ThreadPool來(lái)調(diào)用相關(guān)的函數(shù)。其中向線程池中加入線程的函數(shù)就是ThreadPool.QueueUserWorkItem(new WaitCallBack(), object obj)。這個(gè)函數(shù)有個(gè)WaitCallBack的委托,[ComVisibleAttribute(true)]
public delegate void WaitCallback(Object state)

通過(guò)這個(gè)委托我們也可以傳遞參數(shù)到線程中。

其實(shí)還有一種方法可以傳遞參數(shù)到線程中,那就是通過(guò)回調(diào)函數(shù)來(lái)實(shí)現(xiàn),只不過(guò)這種方法本質(zhì)上和第一種通過(guò)類的數(shù)據(jù)成員來(lái)傳遞參數(shù)的機(jī)制一樣。所以就不再細(xì)說(shuō)來(lái)!

具體的實(shí)現(xiàn)可以參考下面的源代碼:

全部源代碼如下:(該程序在vs 2005編譯通過(guò))

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委托來(lái)傳遞參數(shù)
   rc.col = 19;
   to2.Character = '#';
   Thread thrdt = new Thread(new ParameterizedThreadStart(to2.Output));
   thrdt.Start(rc);
   thrdt.Join();
  }

 }
}

相關(guān)文章

  • 一文帶你了解WPF中的附加事件

    一文帶你了解WPF中的附加事件

    附加事件可用于在非元素類中定義新的 路由事件 ,并在樹中的任何元素上引發(fā)該事件。本文通過(guò)簡(jiǎn)單的示例為大家講解一下WPF附加事件的用法,需要的可以參考一下
    2022-12-12
  • C#開發(fā)微信門戶及應(yīng)用(2) 微信消息處理和應(yīng)答

    C#開發(fā)微信門戶及應(yīng)用(2) 微信消息處理和應(yīng)答

    文章主要為大家詳細(xì)介紹了C#開發(fā)微信門戶及應(yīng)用第二篇,微信消息處理和應(yīng)答,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 詳解C#實(shí)現(xiàn)MD5加密的示例代碼

    詳解C#實(shí)現(xiàn)MD5加密的示例代碼

    本篇文章主要介紹了C#實(shí)現(xiàn)MD5加密的示例代碼,詳細(xì)的介紹了幾種方法,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-12-12
  • C#中的DateTime是值類型還是引用類型

    C#中的DateTime是值類型還是引用類型

    近期遇到了DateTime到底是值類型還是引用類型的疑惑,順勢(shì)較深入地了解一下DateTime相關(guān)的內(nèi)容,大家有需要的朋友可以參考下
    2017-04-04
  • unity實(shí)現(xiàn)手游虛擬搖桿

    unity實(shí)現(xiàn)手游虛擬搖桿

    這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)手游虛擬搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • c# 利用易福門振動(dòng)模塊VSE002采集振動(dòng)數(shù)據(jù)的方法

    c# 利用易福門振動(dòng)模塊VSE002采集振動(dòng)數(shù)據(jù)的方法

    這篇文章主要介紹了c# 利用易福門振動(dòng)模塊VSE002采集振動(dòng)數(shù)據(jù)的方法,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • C#實(shí)現(xiàn)百分比轉(zhuǎn)小數(shù)的方法

    C#實(shí)現(xiàn)百分比轉(zhuǎn)小數(shù)的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)百分比轉(zhuǎn)小數(shù)的方法,涉及C#進(jìn)行數(shù)值計(jì)算的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • Unity?UGUI的MaskableGraphic可遮罩圖形組件介紹使用

    Unity?UGUI的MaskableGraphic可遮罩圖形組件介紹使用

    這篇文章主要為大家介紹了Unity?UGUI的MaskableGraphic可遮罩圖形組件介紹使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • C#獲取指定目錄下指定文件的方法

    C#獲取指定目錄下指定文件的方法

    這篇文章介紹了C#獲取指定目錄下指定文件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 深入談?wù)凜#9新特性的實(shí)際運(yùn)用

    深入談?wù)凜#9新特性的實(shí)際運(yùn)用

    這篇文章主要給大家介紹了C#9新特性的實(shí)際運(yùn)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論