Thread 與 ThreadPool class example
一、Thread
1、範例一
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Thread tTom = new Thread(TomToRun);
Thread tBill = new Thread(BillToRun);
tTom.Start();
tBill.Start();
Console.ReadKey();
}
public static void TomToRun()
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine("Tom Run: {0} meter", i);
}
}
public static void BillToRun()
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine("Bill Run: {0} meter", i);
}
}
}
}
在 CPU 四核心的執行畫面為:
在 CPU 單核心的執行畫面為:
說明:
a、在程式碼上,由於是 tTom 先開始跑的,之後 tBill 也跟著跑,
所以畫面上一定會是第一個出現「Tom Run: 0 meter」訊息,而不是「Bill Run: 0 meter」訊息。
2、範例二、使用 join 方法,讓其執行完全跑完,才可以讓別的執行緒跑
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Thread tTom = new Thread(TomToRun);
Thread tBill = new Thread(BillToRun);
tTom.Start();
tTom.Join();
tBill.Start();
Console.ReadKey();
}
public static void TomToRun()
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine("Tom Run: {0} meter", i);
}
}
public static void BillToRun()
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine("Bill Run: {0} meter", i);
}
}
}
}
執行畫面為:
3、其他範例
using System;
using System.Threading;
namespace test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main thread: Start a second thread.");
// The constructor for the Thread class requires a ThreadStart
// delegate that represents the method to be executed on the
// thread. C# simplifies the creation of this delegate.
Thread t = new Thread(ThreadProc);
// Start ThreadProc. Note that on a uniprocessor, the new
// thread does not get any processor time until the main thread
// is preempted or yields. Uncomment the Thread.Sleep that
// follows t.Start() to see the difference.
t.Start();
Thread.Sleep(0);
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Main thread: Do some work. " + i);
Thread.Sleep(0);
}
Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends.");
t.Join();
Console.WriteLine("Main thread: ThreadProc.Join has returned. Press Enter to end program.");
Console.ReadKey();
}
public static void ThreadProc()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
// Yield the rest of the time slice.
Thread.Sleep(0);
}
}
}
}
說明:
a、寫法 Thread t = new Thread(ThreadProc); 或是
Thread t = new Thread(new ThreadStart(ThreadProc)); 寫法,都是一樣的。
二、ThreadPool
using System;
using System.Threading;
namespace test
{
class Program
{
static void Main(string[] args)
{
// Queue the task.
ThreadPool.QueueUserWorkItem(ThreadProc);
Console.WriteLine("Main thread {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
Console.WriteLine("exits. {0}", Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
static void ThreadProc(Object stateInfo)
{
// No state object was passed to QueueUserWorkItem, so stateInfo is null.
Console.WriteLine("ThreadProc {0}", Thread.CurrentThread.ManagedThreadId);
}
}
}
說明:
ThreadPool.QueueUserWorkItem(ThreadProc); 和
Console.WriteLine("Main thread {0}", Thread.CurrentThread.ManagedThreadId);
會有同等優先權,也就是說兩者都有機會搶第一先被執行。
三、總結
1、Thread 與 ThreadPool 在 .NET framework 1.1 就有提供了,看來真的有歷史耶。
2、Thread 與 ThreadPool 無法得知執行緒工作何時完成,以及當工作完成時也無法取得其執行結果。
3、I/O-Bound 適用多執行緒處理,CPU-Bound 適用非同步處理。
參考資料: