我們知道,使用多線程可以提高程序運行的效率,加速程序的運行。但是我們也應該知道每個線程都要耗費許多資源,在程序中不是運行的線程越多好,我們要掌握如何充分利用多線程的優勢。要儘量使線程運行,不要讓它掛起,因爲掛起的線程不再運行。但是仍然耗費系統資源。
線程池是一種非常好的技術,可以大大提高程序的效率,而且又把新建每個線程的消耗降到最小。下面我們看一下c#中提供的有關線程池的方法以及如何使用:
static Boolean QueueUserWorkItem(WaitCallback callBack, Object state);
static Boolean UnsafeQueueUserWorkItem(WaitCallback callBack, Object state);
using System;
using System.Threading;
public static class Program {
public static void Main() {
Console.WriteLine("Main thread: queuing an asynchronous operation");
ThreadPool.QueueUserWorkItem(ComputeBoundOp, 5);
Console.WriteLine("Main thread: Doing other work here...");
Thread.Sleep(10000);
Console.WriteLine("Hit <Enter> to end this program...");
Console.ReadLine();
}
private static void ComputeBoundOp(Object state) {
Console.WriteLine("In ComputeBoundOp: state={0}", state);
Thread.Sleep(1000);
}
}
//有時候是這樣的結果
Main thread: queuing an asynchronous operation
Main thread: Doing other work here...
In ComputeBoundOp: state=5
//有時候又是這樣的結果
Main thread: queuing an asynchronous operation
In ComputeBoundOp: state=5
Main thread: Doing other work here...
//我們看出兩個線程的調度是由系統決定的,我們是無法選擇的。
下面再來看一下使用專用線程,我們知道如果程序只需要其他的1~2線程來輔助程序運行,這種情況下用線程池恐怕不是很適合,而使用專用線程比較好:
using System.Threading;
public static class Program {
public static void Main() {
Console.WriteLine("Main thread: starting a dedicated thread " +"to do an asynchronous operation");
Thread dedicatedThread = new Thread(ComputeBoundOp);
dedicatedThread.Start(5);
Console.WriteLine("Main thread: Doing other work here...");
Thread.Sleep(10000);
dedicatedThread.Join(); //等待線程終止
Console.WriteLine("Hit <Enter> to end this program...");
Console.ReadLine();
}
private static void ComputeBoundOp(Object state) {
Console.WriteLine("In ComputeBoundOp: state={0}", state);
Thread.Sleep(1000);
}
}
//同樣是兩種輸出結果
Main thread: starting a dedicated thread to do an asynchronous operation
Main thread: Doing other work here...
In ComputeBoundOp: state=5
Main thread: starting a dedicated thread to do an asynchronous operation
In ComputeBoundOp: state=5
Main thread: Doing other work here...
下面看一下定期執行某種操作我們應該如何使用定時器:
using System.Threading;
public static class Program {
public static void Main() {
Console.WriteLine("Main thread: starting a timer");
Timer t = new Timer(ComputeBoundOp, 5, 0, 2000);
Console.WriteLine("Main thread: Doing other work here...");
Thread.Sleep(10000);
t.Dispose();
}
private static void ComputeBoundOp(Object state) {
Console.WriteLine("In ComputeBoundOp: state={0}", state);
Thread.Sleep(1000); // Simulates other work (1 second)
}
}
如果我們查看FCL的話,我們會看到三個Timer類,下面分別介紹一下他們:
System.Windows.Forms.Timer
/*構建一個該類的實例可以告訴Windows將定時器與調用線程關聯。隨着定時器的觸發,Windows將一個定時消息插入到線程的消息隊列中。調用線程必須執行一個消息循環,從而提取消息,並分別將他們分派到希望的回調方法中。*/
System.Timers.Timer
/*該定時器基本上是對System.Threading.Timer 的一個封裝,當定時器到期後,經導致FCL將事件加入線程池隊列中。這個定時器有可能被移除,以便都使用System.Threading.Timer */