C#基礎(chǔ)–線程Thread和線程池ThreadPool
一、線程 Thread
1. 開啟一個線程
ThreadStart 是屬于System.Threading 中的一個內(nèi)置委托
ThreadStart threadStart = () =>
{
this.DoSomethingLong("btnThread_Click");
};
Thread thread = new Thread(threadStart); //傳入委托
thread.Start(); //開啟一個新線程
ParameterizedThreadStart 是屬于System.Threading 中的一個內(nèi)置委托
ParameterizedThreadStart threadStart = ar =>
{
this.DoSomethingLong("btnThread_Click");
};
Thread thread = new Thread(threadStart);
thread.Start(); //開啟一個新線程
2. 暫停/恢復(fù)線程
無法實時的去 “暫停 ” 或者 “恢復(fù)” 線程,因為線程是由系統(tǒng)調(diào)度執(zhí)行的,而且中間存在一個延時現(xiàn)象,不可能直接幫你執(zhí)行
thread.Suspend(); // 暫停線程
thread.Resume(); //恢復(fù) 無法實時的去暫停或者恢復(fù)線程
3. 終結(jié)線程
在調(diào)用Abort()方法的線程上引發(fā) System.Threading.ThreadAbortException,以開始終止此線程的過程。 調(diào)用此方法通常會終止線程。
Thread.ResetAbort() 也會存在一定的延遲問題
thread.Abort(); //終結(jié)線程
Thread.ResetAbort(); //終結(jié)的線程繼續(xù)執(zhí)行
4. 等待任務(wù)
根據(jù)線程狀態(tài)等待
ThreadState 是一種枚舉類型
while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(200);
}
Join等待
限時等待,和委托中的 WaitOne等待 很像
thread.Join(); //無限時等待
thread.Join(2000); //最多等待2000毫秒
5. 線程調(diào)度優(yōu)先級
Priority 是一種枚舉類型,設(shè)置了的話只是增加它的優(yōu)先概率,并不能一定能保證它實現(xiàn)正確的優(yōu)先級執(zhí)行(因為CPU是分核的)
thread.Priority = ThreadPriority.Highest;
6. 后臺/前臺線程
后臺線程:進程結(jié)束,線程也結(jié)束;例如,winform 功能在控制臺輸出,關(guān)閉winform窗體,控制臺窗口也會立即關(guān)閉
前臺線程:進程結(jié)束后,任務(wù)執(zhí)行完畢以后,線程才結(jié)束;例如,winform 功能在控制臺輸出,關(guān)閉winform窗體,控制臺窗口只有等線程任務(wù)完成后才會關(guān)閉
thread.IsBackground = true; //后臺線程 進程結(jié)束,線程結(jié)束了
thread.IsBackground = false; //前臺線程 進程結(jié)束后,任務(wù)執(zhí)行完畢以后,線程才結(jié)束
二、線程 Thread 擴展
1. 無返回結(jié)果
private void ThreadWithCallBack(ThreadStart threadStart, Action actionCallback)
{
ThreadStart threadStart = new ThreadStart(() =>
{
threadStart.Invoke();
actionCallback.Invoke();
});
Thread thread = new Thread(threadStart);
thread.Start();
}
ThreadStart threadStart1 = () =>
{
Console.WriteLine("執(zhí)行任務(wù)");
};
Action action = () =>
{
Console.WriteLine("執(zhí)行回調(diào)");
};
this.ThreadWithCallBack(threadStart1, action);
2. 開啟一個線程,并獲取返回結(jié)果
擴展方法內(nèi)部開啟一個線程執(zhí)行任務(wù) – 執(zhí)行傳入的委托
線程等待的工作封裝到另外一個委托,將委托返回出去,讓外部執(zhí)行:這樣就不會造成封裝方法內(nèi)阻塞(卡界面),調(diào)用封裝方法的程序可以繼續(xù)執(zhí)行之后的代碼
需要結(jié)果的時候,再去執(zhí)行返回的委托;如果不需要的結(jié)果的話,就不必再去執(zhí)行返回的委托了
/// <summary>
/// 既要不卡界面,又需要返回結(jié)果
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
private Func<T> ThreadWithReturn<T>(Func<T> func)
{
T t = default(T);
ThreadStart threadStart = new ThreadStart(() =>
{
t = func.Invoke();
});
Thread thread = new Thread(threadStart);
thread.Start();
return new Func<T>(() =>
{
thread.Join();
return t;
});
}
Func<int> func = () =>
{
Thread.Sleep(5000);
return DateTime.Now.Year;
};
Func<int> FuncResult = this.ThreadWithReturn(func);
Console.WriteLine("同步執(zhí)行操作1--發(fā)短信");
Console.WriteLine("同步執(zhí)行操作2--發(fā)郵件");
Console.WriteLine("同步執(zhí)行操作3--統(tǒng)計信息");
Console.WriteLine("同步執(zhí)行操作4--更新ES數(shù)據(jù)");
int iResult = FuncResult.Invoke(); //如果需要得到執(zhí)行結(jié)果,是必須要等待的
三、線程池 ThreadPool
.NetFramework2.0 出現(xiàn)的
在Thread中對線程的管理需要我們自己去從操作,在不斷的開啟線程和銷毀中,存在很大的開銷,為了讓線程可以反復(fù)的使用,出現(xiàn)了池化思想!
線程池不僅可以節(jié)省資源,還可以控制線程總數(shù)量,防止濫用!
1. 開啟一個線程
ThreadPool.QueueUserWorkItem 需要傳入一個WaitCallback委托作為參數(shù)
WaitCallback是 System.Threading 內(nèi)置的一個委托
ThreadPool.QueueUserWorkItem(o =>
{
this.DoSomethingLong("ThreadPool.QueueUserWorkItem1"); //開啟了一個線程
});
ThreadPool.QueueUserWorkItem(o =>
{
Console.WriteLine($"第二個參數(shù):{o}");
this.DoSomethingLong("ThreadPool.QueueUserWorkItem1");//開啟了一個線程
}, "Hyl");
2. 設(shè)置/獲取 最大最小線程
設(shè)置線程數(shù)量是全局,線程池是全局,Task、async/awit 都是來自于線程,所以本人不建議大家隨便設(shè)置!
設(shè)置線程最大數(shù)量的時候,數(shù)量不能低于本計算機的核數(shù),否則設(shè)置無效。如下圖效果圖:(2047,1000 是默認(rèn)設(shè)置)
ThreadPool.SetMaxThreads(2, 2); //這里在設(shè)置的時候,數(shù)量不能低于本計算機的 核數(shù)
ThreadPool.SetMinThreads(2, 2);
ThreadPool.GetMaxThreads(out int maxWorkerThreads1, out int maxCompletionPortThreads1);
ThreadPool.GetMinThreads(out int minWorkerThreads1, out int minCompletionPortThreads1);
Console.WriteLine($"當(dāng)前電腦最大workerThreads={maxWorkerThreads1},最大的completionPortThreads={maxCompletionPortThreads1}");
Console.WriteLine($"當(dāng)前電腦最小workerThreads={minWorkerThreads1},最小的completionPortThreads={minCompletionPortThreads1}");
文章來源:http://www.zghlxwxcb.cn/news/detail-588508.html
3. 線程等待
ManualResetEvent manualResetEvent = new ManualResetEvent(false); //開關(guān)關(guān)閉
ThreadPool.QueueUserWorkItem(o =>
{
this.DoSomethingLong("btnThreadPool_Click1");
Thread.Sleep(3000);
manualResetEvent.Set();// 開關(guān)打開
});
manualResetEvent.WaitOne(); //執(zhí)行到這兒來的時候,我就等你給我發(fā)信號
Console.WriteLine("計算完成");
文章來源地址http://www.zghlxwxcb.cn/news/detail-588508.html
到了這里,關(guān)于C#基礎(chǔ)--線程Thread和線程池ThreadPool的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!