厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(11)---各種線程相關操作類


俗話說,一個好漢十個幫,眾人拾柴火焰高等都說明一個道理,有更多的資源,更豐富的積累,都是助你走向成功,走向頂峰的推動力。

本篇的公用類庫的介紹主題是程序開發中多線程操作環境中,常用到的線程相關類,本篇隨筆介紹包含單件創建輔助類、Timer定時器、委托處理輔助類、隊列的線程處理服務輔助類、可以取消執行操作的線程池輔助類、線程池輔助類、線程輔助類等對象,這些輔助類覆蓋了多線程開發中絕大多數的應用。良好的封裝及操作,給我們提供非常方便、高效的線程操作處理。

本篇繼續繼續整理優化已有的共用類庫,並繼續發表隨筆介紹公用類庫的接口方法以及詳細使用操作,力求給自己繼續優化,積攢更豐富的公用類庫資源,加深了解的同時,也給大家展現公用類庫好的方面。

厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(10)---各種線程同步的集合類
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(9)----各種常用輔助類
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(8)----非對稱加密、BASE64加密、MD5等常用加密處理
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(7)-----聲音播放、硬件信息、鍵盤模擬及鈎子、鼠標模擬及鈎子等設備相關 
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(6)----全屏截圖、圖標獲取、圖片打印、頁面預覽截屏、圖片復雜操作等
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(5)----熱鍵、多線程、窗體動畫凍結等窗體操作
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(4)----CSV、Excel、INI文件、獨立存儲等文件相關
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(3)----數據庫相關操作
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(2)----常用操作
厚積薄發,豐富的公用類庫積累,助你高效進行系統開發(1)----開篇總結

1、單件操作輔助類 Singleton。  

實現效果

1) 本輔助類主要是用來方便實現類對象的單件實例操作,減少重復寫單件實現代碼的繁瑣,簡化類的代碼。 

2)創建一個類對象的單件實例,類對象的構造函數不能為Public修飾符的,一般為private。

 

實現代碼

1)輔助類提供的方法源碼如下所示: 

/// <summary>    
/// 創建一個類對象的單件實例,類對象的構造函數不能為Public修飾符的,一般為private。
/// </summary>
/// <typeparam name="T">待創建的對象類</typeparam>
public static class Singleton<T> where T : class
{
static volatile T _instance;
static object _lock = new object();

static Singleton()
{
}

/// <summary>
/// 創建/獲取一個可以new的類對象的單件實例
/// </summary>
public static T Instance
{
get
{
if (_instance == null)
lock (_lock)
{
if (_instance == null)
{
ConstructorInfo constructor = null;

try
{
// 構造函數不包含public修飾符的
constructor = typeof(T).GetConstructor(BindingFlags.Instance |
BindingFlags.NonPublic, null, new Type[0], null);
}
catch (Exception exception)
{
throw new InvalidOperationException(exception.Message, exception);
}

if (constructor == null || constructor.IsAssembly)
{
throw new InvalidOperationException(string.Format("在'{0}'里面沒有找到private或者protected的構造函數。", typeof(T).Name));
}

_instance = (T)constructor.Invoke(null);
}
}

return _instance;
}
}

2)輔助類Singleton的使用例子代碼如下所示

/// <summary>    
/// 單件測試類
/// </summary>
public class TestSingletonClass
{
/// <summary>
/// 私有構造函數
/// </summary>
private TestSingletonClass()
{
}

public void ShowMessage()
{
MessageUtil.ShowTips("單件實例測試函數");
}
}

private void btnSingleton_Click(object sender, EventArgs e)
{
//單件輔助類使用代碼
Singleton<TestSingletonClass>.Instance.ShowMessage();
}


如果沒有使用單件輔助類,那么單件的測試類將會需要這樣書寫,很明顯多了很多行代碼,如果每個想單件處理的類都要這樣寫,代碼量還是很可觀的,而且比較繁瑣。

/// <summary>    
/// 單件測試類
/// </summary>
public class TestSingletonClass
{
private static TestSingletonClass m_Instance;

/// <summary>
/// 單件實例
/// </summary>
public static TestSingletonClass Instance
{
get
{
if (m_Instance == null)
{
m_Instance = new TestSingletonClass();
}
return m_Instance;
}
}

/// <summary>
/// 私有構造函數
/// </summary>
private TestSingletonClass()
{
}

public void ShowMessage()
{
MessageUtil.ShowTips("單件實例測試函數");
}
}

 

2、定期執行某些任務的定時器輔助類Timer。  

實現效果

1)  本輔助類主要是用來方便實現定時器輔助類,功能和另外一個定時器輔助類TimerHelper差不多。

2) 定時器操作,都通過對象鎖以及在運行處理事件的時候,動態改變間隔事件為無限等待,處理完成后修改為間隔時間的方式,實現對定時器的正常、安全執行,不會發生運行一半又跳到下一個的處理過程中。 

3).NET提供了3種定時器實現,他們的特點如下所示。該Timer輔助類是基於Threading.Timer的定時器實現。

Server Timers System.Timers.Timer 基於服務器的計時器,位於"工具箱"的“組件”選項卡上
Thread Timers System.Threading.Timer 在編程時使用的線程計時器
Windows Timers System.Windows.Forms.Timer 基於 Windows 的標准計時器,"工具箱"的"Windows 窗體"選項卡上;

實現代碼

1)輔助類提供的方法接口如下所示: 

#region 事件或屬性    

/// <summary>
/// 按定時器周期定期引發的事件
/// </summary>
public event EventHandler Elapsed;

/// <summary>
/// 定時器任務間隔(毫秒)
/// </summary>
public int Period { get; set; }

/// <summary>
/// 指示是否在方法開始的時候,啟動定時器Elapsed事件一次。默認為false。
/// </summary>
public bool RunOnStart { get; set; }

#endregion

#region 構造函數

/// <summary>
/// 創建一個定時器
/// </summary>
/// <param name="period">定時器間隔 (毫秒)</param>
public Timer(int period) : this(period, false)

/// <summary>
/// 創建一個定時器
/// </summary>
/// <param name="period">定時器間隔 (毫秒)</param>
/// <param name="runOnStart">指示是否在方法開始的時候,啟動定時器Elapsed事件一次</param>
public Timer(int period, bool runOnStart)

#endregion

#region 方法

/// <summary>
/// 啟動定時器
/// </summary>
public void Start()

/// <summary>
/// 停止定時器
/// </summary>
public void Stop()

/// <summary>
/// 等待定時器停止
/// </summary>
public void WaitToStop()


#endregion

2)輔助類Timer 的使用例子代碼如下所示

private void btnTimer_Click(object sender, EventArgs e)    
{
WHC.OrderWater.Commons.Threading.Timer timer = new WHC.OrderWater.Commons.Threading.Timer(1000, true);
timer.Elapsed += new EventHandler(timer_Elapsed);
timer.Start();
}

void timer_Elapsed(object sender, EventArgs e)
{
if (!this.InvokeRequired)
return;

this.Invoke(new MethodInvoker(delegate()
{
this.btnTimer.Text = DateTime.Now.ToLongTimeString();
}));
}

 

3、定時器輔助類TimerHelper,可指定運行間隔、延遲啟動時間等操作。  

實現效果

1) 本輔助類主要是用來方便實現定時器輔助類,可指定運行間隔、延遲啟動時間等操作。功能和另外一個定時器輔助類Timer差不多。 

2)定時器操作,都通過對象鎖以及在運行處理事件的時候,動態改變間隔事件為無限等待,處理完成后修改為間隔時間的方式,實現對定時器的正常、安全執行,不會發生運行一半又跳到下一個的處理過程中。 

 

實現代碼

1)輔助類提供的方法接口如下所示: 

 

/// <summary>    
/// 定時器執行操作的函數原型
/// </summary>
public delegate void TimerExecution();

/// <summary>
/// 定時器執行時調用的操作
/// </summary>
public event TimerExecution Execute;

/// <summary>
/// 創建一個指定時間間隔的定時器,並在指定的延遲后開始啟動。(默認間隔為100毫秒)
/// </summary>
public TimerHelper()

/// <summary>
/// 創建一個指定時間間隔的定時器,並在指定的延遲后開始啟動。
/// </summary>
/// <param name="interval">定時器執行操作的間隔時間(毫秒)</param>
/// <param name="startDelay">指定的延遲時間(毫秒)</param>
public TimerHelper(long interval, int startDelay)

/// <summary>
/// 創建一個指定時間間隔的定時器
/// </summary>
/// <param name="interval">定時器執行操作的間隔時間(毫秒)</param>
/// <param name="start">是否啟動</param>
public TimerHelper(long interval, bool start)

/// <summary>
/// 啟動定時器並指定延遲時間(毫秒)
/// </summary>
/// <param name="delayBeforeStart">指定延遲時間(毫秒)</param>
public void Start(int delayBeforeStart)

/// <summary>
/// 立即啟動定時器
/// </summary>
public void Start()

/// <summary>
/// 暫停定時器
/// 注意:運行中的線程不會被停止
/// </summary>
public void Pause()

/// <summary>
/// 停止定時器
/// 注意:運行中的線程不會被停止
/// </summary>
public void Stop()

/// <summary>
/// 定時器的處理時間
/// </summary>
/// <param name="obj"></param>
public void Tick(object obj)

/// <summary>
/// 定時器的狀態
/// </summary>
public TimerState State

/// <summary>
/// 獲取或設置定時器的運行間隔
/// </summary>
public long Interval

2)輔助類TimerHelper的使用例子代碼如下所示

public FrmNewHouse()    
{
InitializeComponent();

if (!this.DesignMode)
{
this.winGridViewPager1.OnPageChanged += new EventHandler(winGridViewPager1_OnPageChanged);
this.winGridViewPager1.OnStartExport += new EventHandler(winGridViewPager1_OnStartExport);
this.winGridViewPager1.OnRefresh += new EventHandler(winGridViewPager1_OnRefresh);
this.winGridViewPager1.OnGridViewMouseDoubleClick += new EventHandler(winGridViewPager1_OnGridViewMouseDoubleClick);
this.winGridViewPager1.ShowLineNumber = true;
this.winGridViewPager1.PagerInfo.PageSize = 20;
this.winGridViewPager1.BestFitColumnWith = true;
this.winGridViewPager1.AppendedMenu = this.contextMenuStrip1;
this.winGridViewPager1.gridView1.RowCellStyle += new DevExpress.XtraGrid.Views.Grid.RowCellStyleEventHandler(gridView1_RowCellStyle);

//使用定時器,定時刷新窗體的數據,並提示客戶更新情況
int interval = Portal.gc.GetRefreshSecond();//獲取定時間隔時間
TimerHelper timer = new TimerHelper(interval, true);
timer.Execute += new TimerHelper.TimerExecution(timer_Execute);
}
}

//通過Invoke來實現跨線程間的調用
void timer_Execute()
{
if (!this.InvokeRequired)
return;

this.Invoke(new MethodInvoker(delegate()
{
NotifyNewHouse();
}));
}


4、提供一個隊列的線程處理服務輔助類 QueueServer。   

實現效果

1)  本輔助類主要是用來方便實現提供一個隊列的線程處理服務操作。QueueServer是一個先入先出(FIFO)的隊列處理服務。

實現代碼

1)輔助類提供的方法接口如下所示: 

#region  屬性方法    

/// <summary>
/// 是否是背景線程
/// </summary>
public bool IsBackground

/// <summary>
/// 執行隊列
/// </summary>
public T[] Items

/// <summary>
/// 隊列數量
/// </summary>
public int QueueCount

/// <summary>
/// 將對象加到隊列結尾
/// </summary>
/// <param name="item"></param>
public void EnqueueItem(T item)

/// <summary>
/// 清除隊列
/// </summary>
public void ClearItems()

#endregion

#region 線程處理

/// <summary>
/// 處理單個元素
/// </summary>
/// <param name="item">元素項目</param>
protected virtual void OnProcessItem(T item)

/// <summary>
/// 處理函數
/// </summary>
public event Action<T> ProcessItem;

#endregion

2)輔助類QueueServer的使用例子代碼如下所示

 private void btnQueneServer_Click(object sender, EventArgs e)    
{
QueueServer<PreDataInfo> queueServer = new QueueServer<PreDataInfo>();
queueServer.IsBackground = true;
queueServer.ProcessItem += new Action<PreDataInfo>(queueServer_ProcessItem);

//循環入隊
for (int i = 0; i < 100; i++)
{
queueServer.EnqueueItem(new PreDataInfo(i.ToString(), DateTime.Now.ToString()));
Thread.Sleep(10);
}
}

/// <summary>
/// 處理每個出隊的操作
/// </summary>
void queueServer_ProcessItem(PreDataInfo obj)
{
Console.WriteLine("{0} : {1}", obj.Key, obj.Data);
}
}

public class PreDataInfo
{
public string Key;
public string Data;

public PreDataInfo()
{
}

public PreDataInfo(string key, string data)
{
this.Key = key;
this.Data = data;
}
}


5、可以取消執行操作的線程池輔助類 AbortableThreadPool。  

實現效果

1) 本輔助類主要是用來方便實現可以取消執行操作的線程池操作。 

2)AbortableThreadPool線程輔助類可以使用常用的多線程處理環境中,也可以使用在有些在運行過程中可能需要取消的線程處理環境中。

 

實現代碼

1)輔助類提供的方法接口如下所示: 

/// <summary>        
/// 把執行操作放到隊列中。當線程池的線程可用的時候,方法執行。
/// </summary>
/// <param name="callback">一個代表將要執行方法的WaitCallback對象</param>
public static WorkItem QueueUserWorkItem(WaitCallback callback)

/// <summary>
/// 把執行操作放到隊列中,並指定了一個對象,它包含將要執行方法的數據。
/// 當線程池的線程可用的時候,方法執行。
/// </summary>
/// <param name="callback">一個代表將要執行方法的WaitCallback對象</param>
/// <param name="state">一個對象,它包含將要執行方法的數據</param>
public static WorkItem QueueUserWorkItem(WaitCallback callback, object state)

/// <summary>
/// 取消指定的隊列中的工作項。
/// </summary>
/// <param name="item">線程池中取消的項目</param>
/// <param name="allowAbort">如果設置為<see langword="true"/>則允許終止線程</param>
/// <returns>項目隊列的狀態</returns>
public static WorkItemStatus Cancel(WorkItem item, bool allowAbort)

/// <summary>
/// 獲取指定隊列中工作項的狀態
/// </summary>
/// <param name="item">線程池中工作項</param>
/// <returns>工作項的狀態</returns>
public static WorkItemStatus GetStatus(WorkItem item)

/// <summary>
/// 取消所有任務
/// </summary>
/// <param name="allowAbort">線程是否終止</param>
public static void CancelAll(bool allowAbort)

/// <summary>
/// 類似Thread.Join,等待AbortableThreadPool執行完成
/// </summary>
public static void Join()

/// <summary>
/// 類似Thread.Join,等待AbortableThreadPool執行完成
/// </summary>
/// <param name="millisecondsTimeout">等待的毫秒數</param>
/// <returns></returns>
public static bool Join(int millisecondsTimeout)

/// <summary>
/// 類似Thread.Join,等待AbortableThreadPool執行完成
/// </summary>
/// <param name="timeout">等待的時間范圍</param>
/// <returns></returns>
public static bool Join(TimeSpan timeout)

/// <summary>
/// 在隊列中,還未執行處理的數量
/// </summary>
public static int QueueCount

/// <summary>
/// 在執行中的線程數量
/// </summary>
public static int WorkingCount

2)輔助類AbortableThreadPool的使用例子代碼如下所示

private void btnAbortableThreadPool_Click(object sender, EventArgs e)    
{
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}", AbortableThreadPool.QueueCount, AbortableThreadPool.WorkingCount));

WorkItem workItem1 = AbortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}", AbortableThreadPool.QueueCount, AbortableThreadPool.WorkingCount));

WorkItem workItem2 = AbortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
WorkItem workItem3 = AbortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
WorkItem workItem4 = AbortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
WorkItem workItem5 = AbortableThreadPool.QueueUserWorkItem(new WaitCallback(Test));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}", AbortableThreadPool.QueueCount, AbortableThreadPool.WorkingCount));
Thread.Sleep(1000);

Console.WriteLine(AbortableThreadPool.Cancel(workItem1, false));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}", AbortableThreadPool.QueueCount, AbortableThreadPool.WorkingCount));
Thread.Sleep(1000);

Console.WriteLine(AbortableThreadPool.Cancel(workItem1, true));
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}", AbortableThreadPool.QueueCount, AbortableThreadPool.WorkingCount));
Thread.Sleep(1000);

//AbortableThreadPool.CancelAll(true);//可取消所有任務
AbortableThreadPool.Join(); //等待所有任務退出
Console.WriteLine(string.Format("QueueCount:{0},WorkingCount:{1}", AbortableThreadPool.QueueCount, AbortableThreadPool.WorkingCount));
}

static void Test(object state)
{
int i = 100;
while (i-- > 0)
{
Console.WriteLine(i);
Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(100));
}
}



6、委托處理輔助類DelegateHelper。  

實現效果

1) 本輔助類主要是用來方便實現委托的處理。 

2)使用委托處理輔助類DelegateHelper,可以快速執行或者取消一些委托方法的執行。

 

實現代碼

1)輔助類提供的方法接口如下所示: 

 

/// <summary>    
/// 執行委托操作
/// </summary>
/// <param name="target">目標委托對象</param>
/// <param name="args">參數</param>
public static WorkItem InvokeDelegate(Delegate target, params object[] args)

/// <summary>
/// 執行委托操作
/// </summary>
/// <param name="target">目標委托對象</param>
public static WorkItem InvokeDelegate(Delegate target)

/// <summary>
/// 中止指定的隊列中委托
/// </summary>
/// <param name="target">目標委托對象</param>
/// <returns>項目隊列中止操作的狀態</returns>
public static WorkItemStatus AbortDelegate(WorkItem target)

2)輔助類DelegateHelper的使用例子代碼如下所示

private void btnDelegeteHelper_Click(object sender, EventArgs e)    
{
//無參數的委托
DelegateHelper.InvokeDelegate(new UpdateTextDelegate(this.UpdateText));

//有參數的委托
DelegateHelper.InvokeDelegate(new UpdateTextDelegate2(this.UpdateText), 100);

}
private delegate void UpdateTextDelegate();
private delegate void UpdateTextDelegate2(int count);
private void UpdateText()
{
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(100);
}
}
private void UpdateText(int count)
{
for (int i = 0; i < count; i++)
{
Thread.Sleep(100);
}
}


7、線程池輔助操作類 ThreadPoolHelper。  

實現效果

1) 本輔助類主要是用來方便實現線程池輔助操作。。 

實現代碼

1)輔助類提供的方法接口如下所示:

/// <summary>    
/// 方法委托
/// </summary>
public delegate void WaitCallbackNew();

/// <summary>
/// 把執行方法放到隊列中。
/// 當線程池線程變為可用的時候,方法執行。
/// </summary>
/// <param name="callback">委托對象</param>
public static bool QueueUserWorkItem(WaitCallbackNew callback)

/// <summary>
/// 把執行方法放到隊列中。
/// 當線程池線程變為可用的時候,方法執行。
/// </summary>
/// <param name="proc">委托對象數組</param>
/// <returns></returns>
public static bool QueueUserWorkItems(params WaitCallbackNew[] proc)

/// <summary>
///等待指定數組中所有元素收到信號
/// </summary>
public static bool WaitAll()

/// <summary>
///等待指定數組中任何一個元素收到信號
/// </summary>
/// <returns>滿足等待的對象數組索引</returns>
public static int WaitAny()

2)輔助類ThreadPoolHelper的使用例子代碼如下所示

private void UpdateText()    
{
for (int i = 0; i < 50; i++)
{
Thread.Sleep(100);
}
}

private void btnThreadPool_Click(object sender, EventArgs e)
{
ThreadPoolHelper.QueueUserWorkItem(new ThreadPoolHelper.WaitCallbackNew(UpdateText));
ThreadPoolHelper.WaitAny(); //阻塞主界面線程,到5秒循環結束后,主界面可以操作
}


8、線程操作輔助類ThreadHelper。 

實現效果

1) 本輔助類主要是用來方便實現線程的各種操作,包括設置線程名稱、優先級等及把執行方法放到隊列中執行等基礎性的線程操作。

 

實現代碼

1)輔助類提供的方法接口如下所示:

 

/// <summary>    
/// 線程名稱,最長不超過10個字符!
/// </summary>
/// <param name="name">線程名稱</param>
public static void SetThreadName(string name)

/// <summary>
/// 設置線程優先級
/// </summary>
/// <param name="priority">線程優先級</param>
public static void SetThreadPriority(ThreadPriority priority)

/// <summary>
/// 設置主線程的UI Culture
/// </summary>
/// <param name="cultureName"></param>
public static void SetMainThreadUICulture(string cultureName)

/// <summary>
/// 把執行方法放到隊列中,並指定了一個對象,它包含使用該方法的數據。
/// 當線程池線程變為可用的時候,方法執行。
/// </summary>
/// <param name="callBack">工作項(WaitCallback)對象</param>
/// <param name="threadName">線程名稱,最長不超過10個字符!</param>
/// <param name="priority">線程優先級</param>
public static bool Queue(WaitCallback callBack, string threadName, ThreadPriority priority)

/// <summary>
/// 把執行方法放到隊列中,並指定了一個對象,它包含使用該方法的數據。
/// 當線程池線程變為可用的時候,方法執行。
/// </summary>
/// <param name="callBack">工作項(WaitCallback)對象</param>
/// <param name="threadName">線程名稱,最長不超過10個字符!</param>
/// <param name="state">執行方法的數據</param>
/// <param name="priority">線程優先級</param>
public static bool Queue(WaitCallback callBack, string threadName, object state, ThreadPriority priority)

/// <summary>
/// 線程休眠一段毫秒時間
/// </summary>
/// <param name="millisecondsTimeout">一段毫秒時間</param>
public static void Sleep(int millisecondsTimeout)

/// <summary>
/// 線程休眠一段時間
/// </summary>
/// <param name="timeOut"></param>
public static void Sleep(TimeSpan timeOut)

2)輔助類ThreadHelper的使用例子代碼如下所示

 

CHM幫助文檔持續更新中,統一下載地址是:  http://www.iqidi.com/download/commonshelp.rar 

最新公用類庫DLL+XML注釋文件下載地址是:http://files.cnblogs.com/wuhuacong/WHC.OrderWater.Commons.rar 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM