熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

VisualC#多線程參數傳遞淺析

2022-06-13   來源: .NET編程 
我們在寫Remoting程序或者其他的一些應用程序的時候難免要和線程打交道使我們很容易就可以創建一個線程但是它提供的創建線程和啟動線程的方法沒有明顯的提供參數假如我們要用線程來啟動類裡面一個帶參數的方法該怎麼辦?下面就簡單的介紹如何使用NET提供的豐富的框架來實現這個功能為了可以生動詳細的介紹整個過程我建立下面的一個NET類它也是要用線程啟動的方法的載體類如下所示

using System;
namespace WindowSAPplication
{
 /// <summary>
 /// Summary description for UrlFetcher
 /// </summary>

 public class MyClass{
  // for method
  private string _parameter;
  public MyClass(string parameter){
   this_parameter = parameter;
  }
 public void MyMethod(){
  if(this_parameter!=null){
   // do something
   ConsoleWrite(this_parameter);
  }
 }
 // for method
 public MyClass(){}
 // this method is privateBut it can be public or other
 private void MyMethod(string parameter){
  // do something
  ConsoleWrite(parameter);
 }
 // Because delegate WaitCallbacks parameter Type is object
 // I will convert it to string
 public void MyMethod(object parameter){
  thisMyMethod((string)parameter);
 }

 // for method
 public string MyMethod(string parameter){
  return 參數值為+parameter;
 }
 // for mutilparameters passed
 public string MyMutilParameters(string paramstring param){
  return 參數和參數連接結果為+param+param;
 }
}
}
  嘿嘿我的英語不行注釋寫的不好請見諒(因為使用的是英文的)希望沒有影響您的閱讀我想我有必要簡單的說一下上面這個類裡裡面的所包含的內容首先包含兩個構造函數一個帶參數一個不帶(這裡可是有意安排的)通過類中其他方法的名字我想您一定猜出來我將介紹種方法來傳遞參數接下來我將逐一介紹首先我們看看如何啟動一個線程首先我們可以用一個函數來實例化ThreadStart委托的一個實例然後在使用這個實例作為參數new線程(Thread)對象最後將這個線程Start就可以了想了解更多請參考MSDN文檔的Thread部分

  為了測試我們的結果我建立了一個WinForm的工程其中有一個Form和個按鈕如果你需要所有的源碼請發送郵件到wu如果我有時間我會給你發過去的接下來是每種方法的詳細描述

  使用構造函數來傳遞參數

  眾所周知我們可以使用一個帶參數的構造函數來構造對象既然這樣我們可以利用構造函數先將要使用的參數值傳遞到對象裡面的內部變量上然後再使用一個無參數的方法來使用這個參數(假裝參數)簡單的說就是在類裡面聲明一個變量專門用來保存函數需要的參數函數變成無參的形式這種方法的最大問題就是破壞了封裝性雖然我們不能直接方法這些變量但是隱患總是存在的(或者說看上去不爽都可以)下面代碼片斷給出了如何使用這個方法來傳遞參數的詳細內容這也是上面提到的個按鈕中的一個按鈕(Button)的Click代碼為了有參數可傳我在WinForm全局定義了一個如下的變量

// This is parameters value
private string myParameter = ParameterValue\n;
  按鈕事件如下所示

// passed parameters to thread by construct

private void button_Click(object sender SystemEventArgs e) {
 MyClass instance = new MyClass(myParameter);
 new Thread (new ThreadStart(instanceMyMethod))Start();
}
  正如上面所說的我們使用構造函數傳遞參數到類裡面去然後在使用上面所說的方法啟動了一個線程我們可以在運行該程序後的output窗口中看到MyMethod的執行結果是(你也可以用一個TextBox或者其他什麼東西直接顯示在WinForm上)ParameterValue 看看函數體就知道這個結果是正確的是不是很簡單

  使用ThreadPool來實現參數的傳遞

  我們首先可以看看MSDN對ThreadPool是怎麼形容的Provides a pool of threads that can be used to post work items process asynchronous I/O wait on behalf of other threads and process timers查看它的方法集合其中有一個叫QueueUserWorkItem 的方法該類以及該方法的詳細信息請參考MSDN相關幫助這裡需要注意的就是QueueUserWorkItem方法的參數參數WaitCallback是一個委托類型第二個參數就是該委托實例(用函數實例化以後也就是一個函數)所需要的參數是object類型的詳細內容請看下面的代碼

// passed parameter to thread by ThreadPool

private void button_Click(object sender SystemEventArgs e) {
 MyClass instance = new MyClass();
 ThreadPoolQueueUserWorkItem (new WaitCallback (instanceMyMethod)myParameter);
}
  因為QueueUserWorkItem的二個參數是object類型的所以我們要在MyClass裡面定義兩個MyMethod的重裁版本目的就是為了滿足該方法的參數同樣我們將參數myParameter傳遞進去了運行程序當我們點擊Button的時候在output窗口中將會出現MyMethod將myParameter作為參數執行的結果顯示出來

  接下來是最後一種方法使用異步委托來實現參數的傳遞

  同樣有關委托的詳細信息可以參考MSDN上面說的非常詳細我們這裡要使用到BeginInvoke和EndInvoke方法首先我們給出傳遞一個參數的方法如下所示

// passed parameter by asynchronous delegate

delegate string MyMethodDelegate(string parameter);

private void button_Click(object sender SystemEventArgs e) {
 MyClass instance = new MyClass();
 MyMethodDelegate myMethod = new MyMethodDelegate(instanceMyMethod);
 myMethodBeginInvoke(parameterValuenew AsyncCallback(AfterMyMothod)null);
}

public void AfterMyMothod(IAsyncResult result){
 AsyncResult async = (AsyncResult) result;
 MyMethodDelegate DelegateInstance = (MyMethodDelegate) asyncAsyncDelegate;
 ConsoleWriteLine (函數調用返回值{}\n DelegateInstanceEndInvoke(result));
}

  首先為了使用委托我們聲明了一個MyMethodDelegate的委托該委托說明一個參數和返回值為string的函數是符合條件的所以我們在MyClass裡面定義了一個MyMethod的方法該函數的型構符合上面的委托所以我們可以在Button點擊的時候用這個方法實例化一個委托然後我們使用異步的方式調用這個方法為了得到返回結果我們寫了AfterMyMothod方法用來顯示該函數的執行結果運行程序點擊Button可以看到Output中輸出的結果為MyMethod帶參數執行的結果最後我給出如何傳遞多個參數的方法我的例子是傳遞個參數代碼如下

// mutilparameters passed

delegate string MyMutilParamsDelegate(string parameterstring parameter);

private void button_Click(object sender SystemEventArgs e) {
 MyClass instance = new MyClass();
 MyMutilParamsDelegate mutilParams = new MyMutilParamsDelegate(instanceMyMutilParameters);

 mutilParamsBeginInvoke(paramparamsnew AsyncCallback(AfterMutilParams)null);
}

public void AfterMutilParams(IAsyncResult result){
 AsyncResult async = (AsyncResult) result;
 MyMutilParamsDelegate DelegateInstance = (MyMutilParamsDelegate) asyncAsyncDelegate;

 ConsoleWriteLine (多參數函數調用返回結果{}\n DelegateInstanceEndInvoke(result));
}
  由於篇幅關系代碼就不作詳細說明了有不正確的地方請指正謝謝閱讀!


From:http://tw.wingwit.com/Article/program/net/201311/12317.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.