爲了控制線程狀態,Thread類中提供了Suspend,Resume,Abort等方法。但Suspend和Resume方法已被MS標註爲已過時(Obsolete),若是簡單的爲線程設置一些狀態量,又會牽扯出跨線程訪問的問題,所以要尋求新的更優的解決方案。在論壇上上看到一篇文章,同時介紹了工作線程在線程池中時的控制方法,很不錯。代碼註釋很全面,一看便懂。
class Program
{
static void Main(string[] args)
{
UseThreadAPI();
UseSyncEvent();
UseThreadPool();
UseSyncEventThreadPool();
Console.WriteLine("All tests finished");
Console.ReadKey();
}
/// <summary>
/// 使用標準Thread API來控制線程狀態,
/// Suspend和Resume是過時的方法,MS不推薦使用
/// MS推薦的方式就是後面要提到的使用Monitor,Event等做同步控制.
/// </summary>
static void UseThreadAPI()
{
Console.WriteLine("----------Use thread API----------");
Thread t = new Thread(
new ThreadStart(() =>
{
while (true)
{
Console.WriteLine("Now Date:{0}", DateTime.Now);
Thread.Sleep(1000);
}
}
));
t.Start();
//暫停線程執行
Console.ReadKey();
t.Suspend();
Console.WriteLine("Thread suspended");
//繼續線程執行
Console.ReadKey();
t.Resume();
Console.WriteLine("Thread resumed");
//結束線程
Console.ReadKey();
t.Abort();
Console.WriteLine("Thread aborted");
Console.ReadKey();
}
/// <summary>
/// 使用Event做同步控制
/// 三個Event組合使用就可以產生同Suspend,Resuem,Abort相同的效果
/// 而且你可以控制Abort的時機以及並作出適當的處理
/// 而不是像Thread.Abort一樣通過異常的方式結束線程
/// </summary>
static void UseSyncEvent()
{
Console.WriteLine("----------Use sync event----------");
AutoResetEvent evtPause = new AutoResetEvent(false);
AutoResetEvent evtResume = new AutoResetEvent(false);
AutoResetEvent evtStop = new AutoResetEvent(false);
Thread t = new Thread(
new ThreadStart(() =>
{
//WaitOne(1000),可產生Sleep(1000)相同的效果
//如果eveStop被置位,則立即返回True,跳出循環
//如果等待1000ms超時,則返回False,繼續循環
while (!evtStop.WaitOne(1000))
{
//WaitOne(0)可立即判斷evtPase有沒有被置位
//如果置位,進入暫停狀態,等待Resume被置位纔會恢復線程執行
if (evtPause.WaitOne(0))
{
//WaitOne()不帶參數表示一直等待,直到被置位
evtResume.WaitOne();
}
Console.WriteLine("Now Date:{0}", DateTime.Now);
}
}
));
t.Start();
//暫停線程執行
Console.ReadKey();
evtPause.Set();
Console.WriteLine("Thread suspended");
//繼續線程執行
Console.ReadKey();
evtResume.Set();
Console.WriteLine("Thread resumed");
//結束線程
Console.ReadKey();
evtStop.Set();
Console.WriteLine("Thread stopped");
Console.ReadKey();
}
class ThreadStatusController
{
/// <summary>
/// 聲明爲volatile可以避免用lock進行加鎖同步
/// 編譯器自己會做優化
/// 另外不能聲明屬性爲volatile,因此只能作爲成員變量放出.
/// </summary>
public volatile bool IsPauseRequired;
public volatile bool IsStopRequired;
}
/// <summary>
/// 對於放入線程池的進程,是無法通過Thread的API進行控制的
/// 通常的做法是通過一些bool量做控制,這不是優雅的解決方案.
/// </summary>
static void UseThreadPool()
{
Console.WriteLine("----------Use thread pool----------");
var tsc = new ThreadStatusController();
ThreadPool.QueueUserWorkItem(status =>
{
var ctrl = status as ThreadStatusController;
//等待IsStopRequired標誌量的值爲True
while (!ctrl.IsStopRequired)
{
//如果不是Pause請求,則執行
if (!ctrl.IsPauseRequired)
Console.WriteLine("Now Date:{0}", DateTime.Now);
Thread.Sleep(1000);
}
}, tsc);
//暫停線程執行
Console.ReadKey();
tsc.IsPauseRequired = true;
Console.WriteLine("Thread suspended");
//繼續線程執行
Console.ReadKey();
tsc.IsPauseRequired = false;
Console.WriteLine("Thread resumed");
//結束線程
Console.ReadKey();
tsc.IsStopRequired = true;
Console.WriteLine("Thread aborted");
Console.ReadKey();
}
/// <summary>
/// 聲明三個同步事件分別對應三種同步狀態
/// </summary>
class ThreadStatusEventController
{
public ThreadStatusEventController()
{
PauseEvent = new AutoResetEvent(false);
ResumeEvent = new AutoResetEvent(false);
StopEvent = new AutoResetEvent(false);
}
public AutoResetEvent PauseEvent { get; set; }
public AutoResetEvent ResumeEvent { get; set; }
public AutoResetEvent StopEvent { get; set; }
}
static void UseSyncEventThreadPool()
{
Console.WriteLine("----------Use sync event with thread pool----------");
var tsc = new ThreadStatusEventController();
ThreadPool.QueueUserWorkItem(status =>
{
var ctrl = status as ThreadStatusEventController;
//控制代碼跟採用Thread的方式類似,不累述
while (!ctrl.StopEvent.WaitOne(1000))
{
if (ctrl.PauseEvent.WaitOne(0))
{
ctrl.ResumeEvent.WaitOne();
}
Console.WriteLine("Now Date:{0}", DateTime.Now);
}
}, tsc);
//暫停線程執行
Console.ReadKey();
tsc.PauseEvent.Set();
Console.WriteLine("Thread suspended");
//繼續線程執行
Console.ReadKey();
tsc.ResumeEvent.Set();
Console.WriteLine("Thread resumed");
//結束線程
Console.ReadKey();
tsc.StopEvent.Set();
Console.WriteLine("Thread aborted");
Console.ReadKey();
}
}
文章來源:http://www.cnblogs.com/bloodish/archive/2011/03/21/1990025.html