1. 程式人生 > >C#多執行緒操作的學習

C#多執行緒操作的學習

當按照先後順序開啟兩個執行緒的時候,第一先開啟的執行緒,執行緒內部任務還未執行完的時候,其實第二個語句已經開始,第二
個語句就是開啟第二,那麼第二個執行緒內部任務會和執行緒一的任務併發執行。優先順序會改變他們的執行頻率。
一、關於開啟執行緒方法兩種:
第一種:
Thread t = new Thread(Worker);
             t.start();
void Worker()
{
  console.WriteLine("這裡是子執行緒要執行的任務");
}
第二種:
例項化一個ThreadStart ,無參代理
 ThreadStart t_start= new ThreadStart(YouWork)
   Thread t=new Thread (t_start);
有引數傳遞,委託,建立執行緒
 ParameterizedThreadStart Para_startThread = new ParameterizedThreadStart(Para_add);//代理委託要執行的函式,引數
是Object型別的函式
                 ThirdThread = new Thread(Para_startThread);//生成一個執行緒
                ThirdThread.Start(Ap);//具體引數在這裡傳遞,這裡傳遞的是一個類物件,這個類物件包含,函式體計算時需要的
引數,同樣也可以傳遞結構體
函式體:
 void Para_add(object Data)//必須具有object型別的形參的函式,可以被ParameterizedThreadStart代理
        {
            if (Data is threadlern)
            {
                threadlern MyData = (threadlern)Data;
                Console.WriteLine("當前執行緒名稱:"+ ThirdThread.Name+""+"當前執行緒
ID:"+Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("MyData.Num:" + MyData.Num+ "MyData.Num02:"+ MyData.Num02);
            }
        }
第三種 執行緒池
後面文章補充
二、關於前臺和後臺執行緒
執行緒池開啟的執行緒預設是後臺執行緒,上面兩種開啟方法,預設開啟的是前臺執行緒。
前臺執行緒意思就是不和主執行緒或程序同時結束了,當主執行緒或程序結束的時候,前臺子執行緒,會讓主執行緒先“回家”,也就是讓主
執行緒先結束,子執行緒這邊執行完了自己結束。
後臺執行緒,就是當主執行緒結束的時候,不管這個後臺子執行緒有沒有“把活兒幹完”,你都得結束。設定後臺執行緒的方法:
t.IsBackground=true;(這是一個可以get,也可以set的屬性)
這樣有個好處,避免你要結束程式的時候,某個子程式任務還沒有完畢,主程式雖然結束,但子程式還在執行,消耗記憶體。
注:一旦這個執行緒使用了t.join();那麼不管前臺執行緒也好後臺也好,主執行緒和子執行緒的關係變為:主執行緒必須等子執行緒把“活兒‘
幹完,主執行緒和子執行緒才能結束,而且是一起結束。關係很親密。
官方例子:
using System;
using System.Threading;
public static class Program {
    public static void Main() {
    // Create a new thread (defaults to foreground)
    Thread t = new Thread(Worker);
    // Make the thread a background thread
    t.IsBackground = true;
    t.Start(); // Start the thread
    // If t is a foreground thread, the application won't die for about 10 seconds
    // If t is a background thread, the application dies immediately
    Console.WriteLine("Returning from Main");
    }
    private static void Worker() {
    Thread.Sleep(10000); // Simulate doing 10 seconds of work
    // The line below only gets displayed if this code is executed by a foreground thread
    Console.WriteLine("Returning from Worker");
    }
}
三、關於多執行緒中使用的一些屬性方法( t.Join()和Thread.sleep(1000)和優先順序Priority;
1. t.Join():等待某子執行緒這個命令的作用,不管你是前臺執行緒也好,後臺執行緒也好,主執行緒必須等待子執行緒結束後再結束,同
樣可以在這裡指定int型引數確定最大等待時間。阻塞呼叫其它執行緒,直到呼叫join();的這個執行緒結束為止。同樣還有另外一個辦
法。從測試中我們可以很清楚的看到MainThread在NewThread.Join被呼叫後被阻塞,直到NewThread 執行完畢才繼續執行。 
注意:當某個子執行緒呼叫Jion(),意思是告訴【主執行緒】等待他執行完,在開始下一句,不管下一句程式碼是什麼。主要說的是【主
執行緒】和【子執行緒】的相互關係。
2.Thread.sleep(1000);這個是Thread中的靜態方法,與執行緒例項物件無關,所以sleep方法寫在那個執行緒執行的過程中,就讓那
個線停留時間。
3.t.Abort();以上兩種主程式等待子程式,或者讓某個程式休眠,這些操作執行完畢後都可以把原來的程式恢復,進而繼續執行
。但是由某個子程式物件呼叫的Abort()執行完畢後,意思是不可恢復性的終止該程式,通知 CLR立即終止。只有重新建立新線
程。
4.執行緒優先順序Priority,所有的執行緒雖然在微觀上是序列執行的,因為出發時間點不同,但是在巨集觀上你完全可以認為它們在並
行執行。執行緒的優先順序只是把執行緒活動的重要程度給CLR,因此優先順序高的並不能保證一定先執行。如果中間執行緒排程器被某
個任務搶佔了優先順序會被修改,就像概率事件一樣,如果優先順序高,執行的頻率就高,因為排程器給予高優先順序的時間片不一
樣。多數情況下不需要修改,使用時小心。
5.t.Name,用執行緒例項物件名呼叫,這是一個可以get和set的屬性。
6.t.IsBackground,讀取或設定BOOL型的變數,確定本執行緒是不是後臺
7.t.start() //告訴CLR,請儘快開啟當前執行緒
8.t.ThreadState,如:Thread Program_T = Thread.CurrentThread;
                        Console.WriteLine(Program_T.ThreadState);
獲取當前執行緒執行狀態,如果不是running,可能是結束或者休眠。
四,關於執行緒開啟的時候,引數傳遞的另一種方法
最好使用無參開啟, ThreadStart t_start= new ThreadStart(YouWork),需要引數傳遞,使用中轉代理函式來傳遞引數,或者使用
ThreadStart t_start= new ThreadStart(YouWork)
   Thread t=new Thread(t_start);
      t.start();
  private void YouWork()//一級代理無引數函式
   {    
   youwork_ori(5,100)
    }
  youwork_ori(int a,int b)//真正要執行的任務
{
   console.Writeline(a+b);
}
五,關於執行緒同步(synchronization)和執行緒非同步(Asynchronous)的理解