開啟執行緒的幾種方式
目錄
執行緒開啟方式(一)-非同步委託
建立執行緒的一種簡單方式是定義一個委託,並非同步呼叫它。 委託是方法的型別安全的引用。Delegate類 還支援非同步地呼叫方法。在後臺,Delegate類會建立一個執行任務的執行緒。
class Program { static int Test(int i, string str) { Console.WriteLine("test" + i + str); Thread.Sleep(100);//讓當前執行緒休眠(暫停執行緒的執行) 單位ms return 200; } static void Main(string[] args) { //在main執行緒中執行 一個執行緒裡面語句的執行 是從上到下的 //1,通過委託 開啟一個執行緒 Func<int, string, int> a = Test; IAsyncResult ar = a.BeginInvoke(30, "siki", null, null);// 開啟一個新的執行緒去執行 a所引用的方法 //IAsyncResult 可以取得當前執行緒的狀態 //可以認為執行緒是同時執行的(非同步執行) Console.WriteLine("main"); while (ar.IsCompleted == false)//如果當前執行緒沒有執行完畢 { Console.Write("."); Thread.Sleep(10); //控制子執行緒的檢測頻率 } int res = a.EndInvoke(ar);//取得非同步執行緒的返回值 Console.WriteLine(res); Console .ReadKey (); } }
執行緒開啟方式(二)-Thread類
我們構造一個thread物件的時候,可以傳遞一個靜態方法,也可以傳遞一個物件的普通方法。
使用Thread類可以建立和控制執行緒。Thread建構函式的引數是一個無參無返回值的委託型別。
在這裡哪個先輸出是無法保證了執行緒的執行有作業系統決定,只能知道Main執行緒和分支執行緒是同步執行的。在這裡給Thread傳遞一個方法,呼叫Thread的Start方法,就會開啟一個執行緒去執行,傳遞的方法。
給執行緒傳遞一些資料可以採用兩種方式,一種方式是使用帶ParameterizedThreadStart委託引數的Thread建構函式,一種方式是建立一個自定義的類,把執行緒的方法定義為例項方法,這樣就可以初始化例項的資料,之後啟動執行緒。
1)傳遞靜態方法
class Program { static void DownloadFile() { Console.WriteLine("開始下載:"+Thread .CurrentThread .ManagedThreadId ); //Thread .CurrentThread .ManagedThreadId 當前執行緒id Thread.Sleep(2000); Console.WriteLine("下載完成"); } static void Main(string[] args) { Thread t = new Thread(DownloadFile);//創建出來Thread物件,這個執行緒並沒有啟動 t.Start();//開始,開始去執行執行緒 Console.WriteLine("Main"); Console.ReadKey(); } }
還可以傳遞引數,方式1:
class Program
{
static void DownloadFile(object fileName)
{
Console.WriteLine("開始下載:" +fileName );
Thread.Sleep(2000);
Console.WriteLine("下載完成");
}
static void Main(string[] args)
{
Thread t = new Thread(DownloadFile);//創建出來Thread物件,這個執行緒並沒有啟動
t.Start("種子");//開始去執行執行緒
Console.WriteLine("下載中...");
Console.ReadKey();
}
}
2)傳遞一個物件的普通方法
class MyThread
{
private string filename;
private string filepath;
public MyThread(string fileName, string filePath)
{
this.filename = fileName;
this.filepath = filePath;
}
public void DownFile()
{
Console.WriteLine("開始下載" + filename + filepath);
Thread.Sleep(2000);
Console.WriteLine("下載完成");
}
}
class Program
{
static void DownloadFile(object fileName)
{
Console.WriteLine("開始下載:" +fileName );
Thread.Sleep(2000);
Console.WriteLine("下載完成");
}
static void Main(string[] args)
{
MyThread my = new MyThread("種子", "http://www.xxx.bbs");
Thread t = new Thread(my.DownFile);
t.Start();
Console.ReadKey();
}
}
3)通過lambda表示式(委託引數的地方都可以使用Lambda表示式)
class Program
{
static void Main(string[] args)
{
//Thread t = new Thread(DownloadFile);//創建出來Thread物件,這個執行緒並沒有啟動
Thread t = new Thread(() =>
{
Console.WriteLine("開始下載:" + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
Console.WriteLine("下載完成");
});
t.Start();//開始,開始去執行執行緒
Console.WriteLine("Main");
Console.ReadKey();
}
}
執行緒開啟方式(三)-執行緒池
建立執行緒需要時間。 如果有不同的小任務要完成,就可以事先建立許多執行緒 , 在應完成這些任務時發出請求。 這個執行緒數最好在需要更多的執行緒時增加,在需要釋放資源時減少。
不需要 自己建立執行緒池,系統已經有一個ThreadPool類管理執行緒。 這個類會在需要時增減池中執行緒的執行緒數,直到達到最大的執行緒數。 池中的最大執行緒數是可配置的。 在雙核 CPU中 ,預設設定為1023個工作執行緒和 1000個 I/o執行緒。也可以指定在建立執行緒池時應立即啟動的最小執行緒數,以及執行緒池中可用的最大執行緒數。 如果有更多的作業要處理,執行緒池中執行緒的個數也到了極限,最新的作業就要排隊,且必須等待執行緒完成其任務。
class Program
{
static void DownloadFile(object fileName)
{
Console.WriteLine("執行緒開始:"+Thread .CurrentThread .ManagedThreadId );
Thread.Sleep(2000);
Console.WriteLine("執行緒結束");
}
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(DownloadFile);
ThreadPool.QueueUserWorkItem(DownloadFile);
ThreadPool.QueueUserWorkItem(DownloadFile);
ThreadPool.QueueUserWorkItem(DownloadFile);
ThreadPool.QueueUserWorkItem(DownloadFile);
Console.ReadKey();
}
}
執行緒開啟方式(四)-任務
class Program
{
static void ThreadMethod()
{
Console.WriteLine("任務開始:");
Thread.Sleep(2000);
Console.WriteLine("任務結束");
}
static void Main(string[] args)
{
//Task t = new Task(ThreadMethod);
//t.Start();也可以
TaskFactory tf = new TaskFactory();
tf.StartNew(ThreadMethod);
Console.WriteLine("main");
Console.ReadKey();
}
}