#region 事件相關
/// <summary>
/// 全部完成事件
/// </summary>
public event Action<CompetedEventArgs> AllCompleted;
/// <summary>
/// 單個完成事件
/// </summary>
public event Action<T, CompetedEventArgs> OneCompleted;
/// <summary>
/// 引發全部完成事件
/// </summary>
/// <param name="args"></param>
private void OnAllCompleted(CompetedEventArgs args)
{
if (AllCompleted != null)
{
try
{
AllCompleted(args);//全部完成事件
}
catch { }
}
}
/// <summary>
/// 引發單個完成事件
/// </summary>
/// <param name="pendingValue"></param>
/// <param name="args"></param>
private void OnOneCompleted(T pendingValue, CompetedEventArgs args)
{
if (OneCompleted != null)
{
try
{
OneCompleted(pendingValue, args);
}
catch { }
}
}
#endregion
#region 構造
public QueueThreadBase(IEnumerable<T> collection)
{
m_InnerQueue = new Queue<T>(collection);
this.m_QueueCount = m_InnerQueue.Count;
}
#endregion
#region 主體
/// <summary>
/// 初始化線程
/// </summary>
private void InitThread()
{
m_ThreadList = new List<Thread>();
for (int i = 0; i < ThreadCount; i++)
{
Thread t = new Thread(new ThreadStart(InnerDoWork));
m_ThreadList.Add(t);
t.IsBackground = true;
t.Start();
}
}
/// <summary>
/// 開始
/// </summary>
public void Start()
{
InitThread();
}
/// <summary>
/// 線程工作
/// </summary>
private void InnerDoWork()
{
try
{
Exception doWorkEx = null;
DoWorkResult doworkResult = DoWorkResult.ContinueThread;
var t = CurrentPendingQueue;
while (!this.Cancel && t.IsHad)
{
try
{
doworkResult = DoWork(t.PendingValue);
}
catch (Exception ex)
{
doWorkEx = ex;
}
m_CompletedCount++;
int precent = m_CompletedCount * 100 / m_QueueCount;
OnOneCompleted(t.PendingValue, new CompetedEventArgs() { CompetedPrecent = precent, InnerException = doWorkEx });
if (doworkResult == DoWorkResult.AbortAllThread)
{
this.Cancel = true;
break;
}
else if (doworkResult == DoWorkResult.AbortCurrentThread)
{
break;
}
t = CurrentPendingQueue;
}
lock (m_AllCompletedLock)
{
m_CompetedCount++;
if (m_CompetedCount == m_ThreadList.Count)
{
OnAllCompleted(new CompetedEventArgs() { CompetedPrecent = 100 });
}
}
}
catch
{
throw;
}
}
/// <summary>
/// 子類重寫
/// </summary>
/// <param name="pendingValue"></param>
/// <returns></returns>
protected virtual DoWorkResult DoWork(T pendingValue)
{
return DoWorkResult.ContinueThread;
}
/// <summary>
/// 獲取當前結果
/// </summary>
private PendingResult CurrentPendingQueue
{
get
{
lock (m_PendingQueueLock)
{
PendingResult t = new PendingResult();
if (m_InnerQueue.Count != 0)
{
t.PendingValue = m_InnerQueue.Dequeue();
t.IsHad = true;
}
else
{
t.PendingValue = default(T);
t.IsHad = false;
}
return t;
}
}
}
#endregion
#region 相關類&枚舉
/// <summary>
/// dowork結果枚舉
/// </summary>
public enum DoWorkResult
{
/// <summary>
/// 繼續運行,默認
/// </summary>
ContinueThread = 0,
/// <summary>
/// 終止當前線程
/// </summary>
AbortCurrentThread = 1,
/// <summary>
/// 終止全部線程
/// </summary>
AbortAllThread = 2
}
/// <summary>
/// 完成事件數據
/// </summary>
public class CompetedEventArgs : EventArgs
{
public CompetedEventArgs()
{
}
/// <summary>
/// 完成百分率
/// </summary>
public int CompetedPrecent { get; set; }
/// <summary>
/// 異常信息
/// </summary>
public Exception InnerException { get; set; }
}
#endregion
}
1.從構造函數來看,處理的是一個確定的列表.沒錯.這個多線程只能處理已經確定的列表,你是否會問.可不可以一邊添加,一邊處理呢?(呵呵,可以,請聯系樓主,當然你也可以自己寫,是吧?!)
2.提供撤銷的功能
3.提供線程個數修改功能
4.提供多種事件響應,如單個完成,全部完成的事件
5.提供完成的百分率
}
/// <summary>
/// 完成百分率
/// </summary>
public int CompetedPrecent { get; set; }
/// <summary>
/// 異常信息
/// </summary>
public Exception InnerException { get; set; }
}
6.提供終止線程的方式,繼續/單線程終止/全部終止
你是否會問?怎么用呢?別急....請看
}
/// <summary>
/// 每次多線程都到這里來,處理多線程
/// </summary>
/// <param name="pendingValue"列表ID></param>
/// <returns></returns>
protected override DoWorkResult DoWork(int pendingID)
{
try
{
//..........多線程處理....
return DoWorkResult.ContinueThread;//沒有異常讓線程繼續跑..
}
catch (Exception)
{
return DoWorkResult.AbortCurrentThread;//有異常,可以終止當前線程.當然.也可以繼續,
//return DoWorkResult.AbortAllThread; //特殊情況下 ,有異常終止所有的線程...
}
//return base.DoWork(pendingValue);
}
}
用法
總結:
多線程在什么時候都會用到.不用到是你不會用.多線程要一定的編程基礎,如果你覺得有點難度,那你可以學習并且借鑒人家已有的東西.少走彎路,是我們程序員經歷嗷嗷待哺后的心聲.本文以交流態度和感恩心態,貢獻給有需要的人們.
新聞熱點
疑難解答