C#線程調用帶參數的方法

在 .NET Framework 2.0 版中,要實現線程調用帶參數的方法有兩種辦法。

第一種:使用ParameterizedThreadStart。

調用 System.Threading.Thread.Start(System.Object) 重載方法時將包含數據的對象傳遞給線程。

使用 ParameterizedThreadStart 委託不是傳遞數據的類型安全的方法,因爲 System.Threading.Thread.Start(System.Object) 方法重載接受任何對象。

這種方法不推薦使用,故在此不做詳細介紹,具體用法參見:http://msdn2.microsoft.com/zh-cn/library/system.threading.parameterizedthreadstart(VS.80).aspx

複製代碼
ParameterizedThreadStart ParStart = new ParameterizedThreadStart(ThreadMethod);
Thread myThread 
= new Thread(ParStart);
object o = "hello";
myThread.Start(o);

//ThreadMethod如下:
public void ThreadMethod(object ParObject)
{
    
//程序代碼
}
複製代碼



第二種:將線程執行的方法和參數都封裝到一個類裏面。通過實例化該類,方法就可以調用屬性來實現間接的類型安全地傳遞參數。

具體代碼如下(本示例來自MSDN)

複製代碼
using System;
using System.Threading;

//ThreadWithState 類裏包含了將要執行的任務以及執行任務的方法
public class ThreadWithState {
    
//要用到的屬性,也就是我們要傳遞的參數
    private string boilerplate;
    
private int value;

    
//包含參數的構造函數
    public ThreadWithState(string text, int number) 
    {
        boilerplate 
= text;
        value 
= number;
    }

    
//要丟給線程執行的方法,本處無返回類型就是爲了能讓ThreadStart來調用
    public void ThreadProc() 
    {
        
//這裏就是要執行的任務,本處只顯示一下傳入的參數
         Console.WriteLine(boilerplate, value); 
    }
}

//用來調用上面方法的類,是本例執行的入口
public class Example {
    
public static void Main() 
    {
        
//實例化ThreadWithState類,爲線程提供參數
        ThreadWithState tws = new ThreadWithState(
            
"This report displays the number {0}."42);

        
// 創建執行任務的線程,並執行
        Thread t = new Thread(new ThreadStart(tws.ThreadProc));
        t.Start();
        Console.WriteLine(
"Main thread does some work, then waits.");
        t.Join();
        Console.WriteLine(
            
"Independent task has completed; main thread ends.");  
    }
}
複製代碼

 

============================================================================

方法一:
在VS2003中,也不能直接訪問,參看  
一般來說,直接在子線程中對窗體上的控件操作是會出現異常,這是由於子線程和運行窗體的線程是不同的空間,因此想要在子線程來操作窗體上的控件,是不可能 簡單的通過控件對象名來操作,但不是說不能進行操作,微軟提供了Invoke的方法,其作用就是讓子線程告訴窗體線程來完成相應的控件操作。  

現在用一個用線程控制的進程條來說明,大致的步驟如下:  

1.創建Invoke函數,大致如下:  
/// <summary>  
/// Delegate function be invoked by main thread  
/// </summary>  
private     void     InvokeFun()  
{  
    if(prgBar.Value< 100)  
    prgBar.Value = prgBar.Value + 1;  
}  

2.子線程入口函數:  
/// <summary>  
/// Thread function interface  
/// </summary>  
private void ThreadFun()  
{  
    // Create invoke method by specific function
    MethodInvoker mi = new MethodInvoker(this.InvokeFun);  

    for(int i=0; i<100; i++)  
    {  
      this.BeginInvoke(mi);    
      Thread.Sleep(100);  
    }  
}

3.創建子線程:  
Thread thdProcess = new Thread(new ThreadStart(ThreadFun));  
thdProcess.Start();  

備註:  
    using System.Threading;  
    private System.Windows.Forms.ProgressBar prgBar;  

方法二:
加入該句:Control.CheckForIllegalCrossThreadCalls = False    取消線線程安全保護模式!

方法三:帶參數
使用類、類的方法或類的屬性都可以向線程傳遞參數:
public class UrlDownloader
{
    string url;
  
    public UrlDownloader (string url)
    {
      this.url = url;
    }
  
    public void Download()
    {
      WebClient wc = new WebClient();
      Console.WriteLine("Downloading " + url);                        
      byte[] buffer = wc.DownloadData (url);
      string download = Encoding.ASCII.GetString(buffer);
      Console.WriteLine(download);
      Console.WriteLine("Download successful.");
    
      //這裏你可以將download進行保存等處理......
    }
}

[... 在另一個類中使用它們...]
              
UrlDownloader downloader = new UrlDownloader (yourUrl);
new Thread (new ThreadStart (downloader.Download)).Start();

注意參數是如何傳遞的。

方法四:帶參數
ThreadStart starter = delegate { Download(yourUrl); };
new Thread(starter).Start();

//使用線程池
WaitCallback callback = delegate (object state) { Download ((string)state); };
ThreadPool.QueueUserWorkItem (callback, yourUrl);

方法五:帶參數
Thread t = new Thread (new ParameterizedThreadStart(DownloadUrl));
t.Start (myUrl);
static void DownloadUrl(object url)
{
  // ....
}

發佈了11 篇原創文章 · 獲贊 3 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章