C#線程進程總結(線程調用帶參數的方法)


新建一個線程,執行一個無參無返回值的方法。
///   <summary>
///  線程調用的方法,無參無返回值
///   </summary>
private  void ThreadMethod()
{ }
啟動線程:
using System.Threading;
ThreadStart threadStart =  new ThreadStart(ThreadMethod);
Thread thread =  new Thread(threadStart);
thread.Start();
thread.Abort();
如果需要執行帶參數的線程:
msdn中推薦的方法是間接調用 
class   thd 

    int   x; 
    int   y; 
    public   thd(int   xx,   int   yy){x=xx;y=yy;} 
    public   void   thstart(){   start(x,   y);} 
    public   void   start(int   a,   int   b){...} 


thd   t   =   new   thd(3,4); 
TheadStart   myd   =   new   TheadStart(t.thstart);

在 .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)
{
  // ....
}

C#進程操作
總結一下進程的新建和終止的操作過程。看代碼:
      public  int CallPhoneExe( string arg)  // arg為進程的命令行參數
      { WaitHandle[] waits = new WaitHandle[ 2];  // 定義兩個WaitHandle值,用以控制進程的執行過程
            waits[ 0] = HSTOP;  // AutoResetEvent HSTOP = new AutoResetEvent(false);
            waits[ 1] = GlobalStop; // AutoResetEvent GlobalStop = new AutoResetEvent(false);
              int iReturn= 0;
             Process p =  new Process(); // 新建一個進程
            p.StartInfo.Arguments = arg;  // 進程的命令行參數
            p.StartInfo.FileName = filepath; // 進程啟動路徑
            
            p.StartInfo.CreateNoWindow =  true; // 不顯示新進程的窗口
            p.StartInfo.RedirectStandardOutput =  true; // 輸出重定向
            p.StartInfo.RedirectStandardError =  true;    // Redirect the error ouput!
            p.StartInfo.UseShellExecute =  false
            p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

            p.EnableRaisingEvents =  true
            p.Exited +=  new EventHandler(p_Exited);  // 進程自然結束后啟動p—Exited事件
            p.OutputDataReceived +=  new DataReceivedEventHandler(ChangeOutput); // 進程有輸出時,啟動ChangeOutPut函數       

            p.Start(); // 進程啟動
            p.BeginOutputReadLine();

             int hstop = WaitHandle.WaitAny(waits); // 啟動線程暫停,知道WaitHandle中傳來有效信號
             switch (hstop) // 判斷信號是又哪個
            {
                 case  0// 進程自然結束
                     if (p.WaitForExit( 2000))
                        iReturn = p.ExitCode;  // 獲取進程的返回值
                     else
                    {
                        CloseProcess();
                        iReturn = - 2;
                    }
                     break;
                 case  1// 進程被迫結束
                    p.Kill(); // 殺掉進程
                     if (!p.HasExited)
                    {                        
                        p.Kill();
                    }                    
                    iReturn = - 3;
                     break;
            }
            HSTOP.Reset();  // HSTOP復位,這個變量指示進程自然結束,每次結束后都得自然復位           
            p.Close();  // 創建的p關閉
             return iReturn;          
        }


         private  void p_Exited( object sender, EventArgs e)
        {
            HSTOP.Set();
        }

// 輸出重定向函數
  private  void ChangeOutput( object sendingProcess, DataReceivedEventArgs outLine)
        {
             if (!String.IsNullOrEmpty(outLine.Data))  // 字符串不為空時
                MainForm.FireWriteText(outLine.Data, false); // 將進程的輸出信息轉移
        }

 

上面總結了新建一個進程的步驟。結束進程的方法可以采用在主線程中將GlobalStop變量設置有效信號,這樣就會調用p.kill()

在系統的所有進程中找尋指定進程的方法:

     foreach (Process p in Process.GetProcesses())
            {
                if (p.ProcessName == "specialProcess")
                {
                    //do smth

                }
                    
            }

url: http://greatverve.cnblogs.com/archive/2012/03/31/csharp-thread-process.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM