01.開啟多線程
class Program
{
static void Main(string[] args)
{
MultiThreadDemo();
Console.ReadKey();
}
//多線程
private static void MultiThreadDemo()
{
//使用線程時首先需要建立線程,使用Thread類構造函數建立執行個體需要用到ThreadStart委托
//或者ParameterizedThreadStart 委托建立 Thread 類的執行個體
//ThreadStart 委托隻能用于無傳回值、無參數的方法
//ParameterizedThreadStart 委托則可以用于帶參數的方法。
//線程不會直接運作,直至調用Start()方法時為止
//建立一個線程,使用Thread類建立線程時,隻需提供線程入口
//(線程入口使程式知道該讓這個線程幹什麼事)
//線程入口是通過ThreadStart代理(delegate)來提供的,
//可以把ThreadStart了解為一個函數指針,指向線程要執行的函數,
//當調用C# Thread.Start()方法後,線程就開始執行ThreadStart所代表或者說指向的函數。
ThreadStart task = () =>
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(String.Format("Thread {0} Out:{1}", Thread.CurrentThread.Name, i));
Thread.Sleep(500);
}
Console.WriteLine(String.Format("Sub Thread {0} The End", Thread.CurrentThread.Name));
};
Thread thread1=new Thread(task)
{
Name = "線程1"
};
thread1.Start();
Thread thread2 = new Thread(task)
{
Name = "線程2"
};
thread2.Start();
Thread thread3 = new Thread(task)
{
Name = "線程3"
};
thread3.Start();
Console.WriteLine("Main Thread Wait For Sub Thread");
}
02.
線程的生命周期
背景線程:在運作過程中如果宿主程序結束,線程将直接終止執行;在強制終止時,線程即終止執行不論線程代碼是否執行完畢。
前台線程:在運作過程中如果宿主程序結束,線程将繼續執行直至線程代碼執行完畢;在強制終止時,線程即結束不論線程代碼是否執行完畢。
是否為背景線程,通過線程對象的 IsBackground 屬性設定
強制終止線程可通過線程對象的Abort()方法進行,同時應該線上程中進行 ThreadAbortException 異常處理,因為在強制結束未執行完成的線程時會抛出該異常。
03.join
當主線程執行到 calculate.threadAdd.Join(); 的時候,并沒有繼續執行,一直等到 加法線程 運算完畢之後主線程才繼續運作,這不就是和MSDN中解釋的一樣嗎?主線程現在就屬于調用線程,當主線程調用了calculate.threadAdd.Join()的時候,就發生了阻塞,直到加法線程運作完畢之後,才繼續運作。
現在我們在來看看Join的另外兩個重載方法:Join(Int32) 和 Join(TimeSpan),這兩個方法其實是一樣的,輸入參數說白了就是設定阻塞的等待時間,傳回值是bool類型,如果線程已終止,則為 true,否則傳回 false
class Program
{
static void Main(string[] args)
{
Calculate calculate=new Calculate();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("主線程輸出:準備進行加法運算:");
calculate.threadAdd.Start();
//主線程現在就屬于調用線程,當主線程調用了calculate.threadAdd.Join()的時候,就發生了阻塞,直到加法線程運作完畢之後,才繼續運作。
calculate.threadAdd.Join();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("主線程輸出:運算完畢");
Console.ReadKey();
}
}
class Calculate
{
public Thread threadAdd;
public Calculate()
{
threadAdd =new Thread(Add);
}
private void Add()
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("進入加法計算");
Thread.Sleep(2000);
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("加法運算結果: x={0} y={1} x+y={2}", 1, 2, 1 + 2);
}
}
04.
using System;
using System.Threading;
namespace ThreadFive
{
class Program
{
static void Main(string[] args)
{
Calculate calculate=new Calculate();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("主線程輸出:準備進行加法運算:");
calculate.threadAdd.Start();
calculate.threadSub.Start();
calculate.threadAdd.Join();
calculate.threadSub.Join();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("主線程輸出:運算完畢");
Console.ReadKey();
}
}
class Calculate
{
public Thread threadAdd;
public Thread threadSub;
public Calculate()
{
threadAdd =new Thread(Add);
threadSub=new Thread(Sub);
}
private void Add()
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("進入加法計算");
Thread.Sleep(4000);
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("加法運算結果: x={0} y={1} x+y={2}", 1, 2, 1 + 2);
}
private void Sub()
{
bool b = threadAdd.Join(1000); //1S之後加法線程沒有執行完成傳回 fslse
if (b)
{
Console.WriteLine("加法運算已經完成,進入減法法計算");
}
else
{
Console.WriteLine("加法運算逾時,先進入減法法計算");
}
Thread.Sleep(2000);
Console.WriteLine("進入減法運算");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("減法運算結果: x={0} y={1} x-y={2}", 10, 2, 10 - 2);
}
}
}