winform開(kāi)發(fā)使用通用多線程基類分享(以隊(duì)列形式)
/// <summary>
/// 隊(duì)列多線程,T 代表處理的單個(gè)類型~
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class QueueThreadBase<T>
{
#region 變量&屬性
/// <summary>
/// 待處理結(jié)果
/// </summary>
private class PendingResult
{
/// <summary>
/// 待處理值
/// </summary>
public T PendingValue { get; set; }
/// <summary>
/// 是否有值
/// </summary>
public bool IsHad { get; set; }
}
/// <summary>
/// 線程數(shù)
/// </summary>
public int ThreadCount
{
get { return this.m_ThreadCount; }
set { this.m_ThreadCount = value; }
}
private int m_ThreadCount = 5;
/// <summary>
/// 取消=True
/// </summary>
public bool Cancel { get; set; }
/// <summary>
/// 線程列表
/// </summary>
List<Thread> m_ThreadList;
/// <summary>
/// 完成隊(duì)列個(gè)數(shù)
/// </summary>
private volatile int m_CompletedCount = 0;
/// <summary>
/// 隊(duì)列總數(shù)
/// </summary>
private int m_QueueCount = 0;
/// <summary>
/// 全部完成鎖
/// </summary>
private object m_AllCompletedLock = new object();
/// <summary>
/// 完成的線程數(shù)
/// </summary>
private int m_CompetedCount = 0;
/// <summary>
/// 隊(duì)列鎖
/// </summary>
private object m_PendingQueueLock = new object();
private Queue<T> m_InnerQueue;
#endregion
#region 事件相關(guān)
/// <summary>
/// 全部完成事件
/// </summary>
public event Action<CompetedEventArgs> AllCompleted;
/// <summary>
/// 單個(gè)完成事件
/// </summary>
public event Action<T, CompetedEventArgs> OneCompleted;
/// <summary>
/// 引發(fā)全部完成事件
/// </summary>
/// <param name="args"></param>
private void OnAllCompleted(CompetedEventArgs args)
{
if (AllCompleted != null)
{
try
{
AllCompleted(args);//全部完成事件
}
catch { }
}
}
/// <summary>
/// 引發(fā)單個(gè)完成事件
/// </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 構(gòu)造
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>
/// 開(kāi)始
/// </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>
/// 子類重寫(xiě)
/// </summary>
/// <param name="pendingValue"></param>
/// <returns></returns>
protected virtual DoWorkResult DoWork(T pendingValue)
{
return DoWorkResult.ContinueThread;
}
/// <summary>
/// 獲取當(dāng)前結(jié)果
/// </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 相關(guān)類&枚舉
/// <summary>
/// dowork結(jié)果枚舉
/// </summary>
public enum DoWorkResult
{
/// <summary>
/// 繼續(xù)運(yùn)行,默認(rèn)
/// </summary>
ContinueThread = 0,
/// <summary>
/// 終止當(dāng)前線程
/// </summary>
AbortCurrentThread = 1,
/// <summary>
/// 終止全部線程
/// </summary>
AbortAllThread = 2
}
/// <summary>
/// 完成事件數(shù)據(jù)
/// </summary>
public class CompetedEventArgs : EventArgs
{
public CompetedEventArgs()
{
}
/// <summary>
/// 完成百分率
/// </summary>
public int CompetedPrecent { get; set; }
/// <summary>
/// 異常信息
/// </summary>
public Exception InnerException { get; set; }
}
#endregion
}
1.從構(gòu)造函數(shù)來(lái)看,處理的是一個(gè)確定的列表.沒(méi)錯(cuò).這個(gè)多線程只能處理已經(jīng)確定的列表,你是否會(huì)問(wèn).可不可以一邊添加,一邊處理呢?(呵呵,可以,請(qǐng)聯(lián)系樓主,當(dāng)然你也可以自己寫(xiě),是吧?!)
public QueueThreadBase(IEnumerable<T> collection)
2.提供撤銷的功能
/// <summary>
/// 取消=True
/// </summary>
public bool Cancel { get; set; }
3.提供線程個(gè)數(shù)修改功能
/// <summary>
/// 線程數(shù)
/// </summary>
public int ThreadCount
{
get { return this.m_ThreadCount; }
set { this.m_ThreadCount = value; }
}
4.提供多種事件響應(yīng),如單個(gè)完成,全部完成的事件
/// <summary>
/// 全部完成事件
/// </summary>
public event Action<CompetedEventArgs> AllCompleted;
/// <summary>
/// 單個(gè)完成事件
/// </summary>
public event Action<T, CompetedEventArgs> OneCompleted;
5.提供完成的百分率
/// <summary>
/// 完成事件數(shù)據(jù)
/// </summary>
public class CompetedEventArgs : EventArgs
{
public CompetedEventArgs()
{
}
/// <summary>
/// 完成百分率
/// </summary>
public int CompetedPrecent { get; set; }
/// <summary>
/// 異常信息
/// </summary>
public Exception InnerException { get; set; }
}
6.提供終止線程的方式,繼續(xù)/單線程終止/全部終止
/// <summary>
/// dowork結(jié)果枚舉
/// </summary>
public enum DoWorkResult
{
/// <summary>
/// 繼續(xù)運(yùn)行,默認(rèn)
/// </summary>
ContinueThread = 0,
/// <summary>
/// 終止當(dāng)前線程
/// </summary>
AbortCurrentThread = 1,
/// <summary>
/// 終止全部線程
/// </summary>
AbortAllThread = 2
}
你是否會(huì)問(wèn)?怎么用呢?別急....請(qǐng)看
/// <summary>
/// 下載線程對(duì)了.
/// </summary>
public class DownLoadQueueThread:QueueThreadBase<int>
{
/// <summary>
///
/// </summary>
/// <param name="list">下載的列表ID</param>
public DownLoadQueueThread(IEnumerable<int> list):base(list)
{
}
/// <summary>
/// 每次多線程都到這里來(lái),處理多線程
/// </summary>
/// <param name="pendingValue"列表ID></param>
/// <returns></returns>
protected override DoWorkResult DoWork(int pendingID)
{
try
{
//..........多線程處理....
return DoWorkResult.ContinueThread;//沒(méi)有異常讓線程繼續(xù)跑..
}
catch (Exception)
{
return DoWorkResult.AbortCurrentThread;//有異常,可以終止當(dāng)前線程.當(dāng)然.也可以繼續(xù),
//return DoWorkResult.AbortAllThread; //特殊情況下 ,有異常終止所有的線程...
}
//return base.DoWork(pendingValue);
}
}
用法
總結(jié):
多線程在什么時(shí)候都會(huì)用到.不用到是你不會(huì)用.多線程要一定的編程基礎(chǔ),如果你覺(jué)得有點(diǎn)難度,那你可以學(xué)習(xí)并且借鑒人家已有的東西.少走彎路,是我們程序員經(jīng)歷嗷嗷待哺后的心聲.本文以交流態(tài)度和感恩心態(tài),貢獻(xiàn)給有需要的人們.
相關(guān)文章
C#基于cookie實(shí)現(xiàn)的購(gòu)物車功能
這篇文章主要介紹了C#基于cookie實(shí)現(xiàn)的購(gòu)物車功能,結(jié)合完整實(shí)例形式分析了C#基于cookie創(chuàng)建購(gòu)物車的具體步驟與相關(guān)技巧,需要的朋友可以參考下2015-12-12
基于C#實(shí)現(xiàn)手機(jī)號(hào)碼歸屬地接口調(diào)用
這篇文章主要介紹了基于C#實(shí)現(xiàn)手機(jī)號(hào)碼歸屬地接口調(diào)用的相關(guān)資料,需要的朋友可以參考下2016-02-02
C#實(shí)體類轉(zhuǎn)換的兩種方式小結(jié)
這篇文章主要介紹了C#實(shí)體類轉(zhuǎn)換的兩種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
c#同步兩個(gè)子目錄文件示例分享 兩個(gè)文件夾同步
這篇文章主要介紹了使用c#同步兩個(gè)子目錄文件的方法,大家參考使用吧2014-01-01
Unity3D Shader實(shí)現(xiàn)掃描顯示效果
這篇文章主要為大家詳細(xì)介紹了Unity3D Shader實(shí)現(xiàn)掃描顯示效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
C#實(shí)現(xiàn)開(kāi)機(jī)自動(dòng)啟動(dòng)設(shè)置代碼分享
這篇文章主要介紹了C#實(shí)現(xiàn)開(kāi)機(jī)自動(dòng)啟動(dòng)設(shè)置代碼分享,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-07-07
C# WinForm國(guó)際化實(shí)現(xiàn)的簡(jiǎn)單方法
這篇文章主要介紹了C# WinForm國(guó)際化實(shí)現(xiàn)的簡(jiǎn)單方法,有需要的朋友可以參考一下2014-01-01
利用C#版OpenCV實(shí)現(xiàn)圓心求取實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于如何利用C#版OpenCV實(shí)現(xiàn)圓心求取的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05

