|
一,摘要
圣殿騎士首先向大家說聲對(duì)不起,由于最近身體不適,同時(shí)也因?yàn)檫@些天一直在研究微軟的云計(jì)算平臺(tái)Windows Azure(公司項(xiàng)目需要),所以暫停了更新WPF 基礎(chǔ)到企業(yè)應(yīng)用系列索引,不過經(jīng)過這幾天的調(diào)節(jié),尤其是到海邊去曬了曬太陽,現(xiàn)在又開始繼續(xù)發(fā)文了,大家有興趣也可以去看看漂亮的大海圖片工作之余的閑暇,今天這篇文章不是專業(yè)談多線程,只是應(yīng)一些朋友的要求對(duì)上篇文章WPF 基礎(chǔ)到企業(yè)應(yīng)用系列4——WPF千年輪回進(jìn)行一些額外的補(bǔ)充,如果有時(shí)間,可以單獨(dú)寫一個(gè)專題來詳細(xì)深入多線程的應(yīng)用,當(dāng)然由于自己才疏學(xué)淺,但渴求對(duì)自己知識(shí)的糾正和提高,所以發(fā)布出來。如有不對(duì)的地方,也希望大家多多海涵!
二,提綱
一,摘要
二,提綱
三,基本概念
四,多線程實(shí)踐
五,總結(jié)
三,基本概念
什么是進(jìn)程?
“進(jìn)程”是操作系統(tǒng)的最基本的,也是最重要的概念之一。簡單來說一個(gè)進(jìn)程就是你正在執(zhí)行的應(yīng)用程序,一個(gè)進(jìn)程里面包括一個(gè)或多個(gè)線程。系統(tǒng)中的一個(gè)進(jìn)程肯定對(duì)應(yīng)著一個(gè)應(yīng)用程序,但同一個(gè)應(yīng)用程序可以有多個(gè)進(jìn)程。所以我們要清楚,進(jìn)程和程序是相關(guān)聯(lián)的,但并不是同一個(gè)概念。即應(yīng)用程序被加載到內(nèi)存中后叫進(jìn)程。
什么是線程?
線程簡單來說就是程序中的一個(gè)執(zhí)行流,每個(gè)線程都有自己的專有寄存器同時(shí)代碼區(qū)是共享的,即不同的線程可以執(zhí)行同樣的函數(shù)和訪問同樣的變量。 即進(jìn)程被CPU處理時(shí)叫線程。
什么是多線程?
多線程簡單的說就是在一個(gè)程序中包含多個(gè)程序流,可以把一個(gè)復(fù)雜的操作分成多個(gè)細(xì)節(jié)操作,這些細(xì)節(jié)操作可以并行的執(zhí)行,從而節(jié)約時(shí)間和提高效率。
多線程優(yōu)點(diǎn):
線程可以有以下一些好處:可以提高CPU的利用率。在一個(gè)多線程程序中,一個(gè)線程處于等待的時(shí)候,CPU可以運(yùn)行其它的線程來處理,這樣就節(jié)約了時(shí)間和提高了程序的效率,同時(shí)也提高了用戶的體驗(yàn)。
多線程缺點(diǎn):
1,線程越多,內(nèi)存占用越大;
2,多線程的運(yùn)行需要互相協(xié)調(diào)和統(tǒng)一管理,CPU會(huì)額外跟蹤線程;
3,線程之間對(duì)共享資源的訪問會(huì)相互影響,必須解決競(jìng)用共享資源的種種問題;
4,線程太多會(huì)導(dǎo)致控制的復(fù)雜度增加,會(huì)引發(fā)不必要的Bug;5,在32位的操作系統(tǒng)和64位的操作系統(tǒng)執(zhí)行的線程、版本不同的操作系統(tǒng)之間執(zhí)行的線程等都有所差異,執(zhí)行順序也有差異。
重要概念(本篇不重點(diǎn)講解)
Start():啟動(dòng)線程;
Sleep(int):暫停當(dāng)前線程指定的毫秒數(shù);
Abort():通常使用該方法來終止一個(gè)線程,但容易出錯(cuò);
Suspend():掛起線程,需要時(shí)可以恢復(fù);
Resume():恢復(fù)被Suspend()方法掛起的線程;程的優(yōu)先級(jí)可以定義為ThreadPriority枚舉的值,即Highest、AboveNormal、Normal、BelowNormal和 Lowest;
創(chuàng)建線程可以用如下三種方式:Thread、ThreadPool、Timer;
.NET Framework內(nèi)置提供了三種Timer:System.Windows.Forms.Timer、System.Timers.Timer和System.Threading.Timer;
線程同步lock,Monitor,同步事件EventWaitHandler,互斥體Mutex、線程池等的使用;
四,多線程實(shí)踐
在本文中我們會(huì)通過11個(gè)小Demo來講解一下多線程的實(shí)踐,講得不是很全面,只是希望給大家一個(gè)參考。由于比較簡單,所以我就不添加累贅的文字介紹,這樣大家看起來也比較舒暢。我會(huì)在文章后面附上代碼,大家可以下載進(jìn)行查看和調(diào)試。
這個(gè)11個(gè)方法都通過Form1_Load調(diào)用,如下面的代碼和圖片:
private void Form1_Load(object sender, EventArgs e)
{
DoWithEasy();
DoWithParameter();
DoWithTimer();
DoWithThreadPool();
DoWithThreadPoolParameter();
DoWithAnonymous();
DoWithLambda();
DoWithCommon();
DoWithAction();
DoWithFunc();
DoWithPredicate();
}
創(chuàng)建一個(gè)簡單的線程:
private void DoWithEasy()
{
Thread t = new Thread(new ThreadStart(this.DoSomethingWithEasy));
t.Start();
}
private void DoSomethingWithEasy()
{
MessageBox.Show("Knights Warrior");
}
創(chuàng)建一個(gè)帶方法的線程:
private void DoWithParameter()
{
Thread t = new Thread(new ParameterizedThreadStart(this.DoSomethingWithParameter));
t.Start("Knights Warrior");
}
private void DoSomethingWithParameter(object x)
{
MessageBox.Show(x.ToString());
}
使用Timer創(chuàng)建線程:
public void DoWithTimer()
{
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += (x, y) =>
{
MessageBox.Show("Knights Warrior");
};
timer.Start();
}
通過ThreadPool創(chuàng)建無參線程:
private void DoWithThreadPool()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomethingWithThreadPoolNO));
}
private void DoSomethingWithThreadPoolNO(object x)
{
MessageBox.Show("Knights Warrior");
}
通過ThreadPool創(chuàng)建有參線程:
private void DoWithThreadPoolParameter()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomethingWithThreadPoolParameter), "Knights Warrior");
}
private void DoSomethingWithThreadPoolParameter(object x)
{
MessageBox.Show(x.ToString());
}
通過匿名委托方式創(chuàng)建線程:
private void DoWithAnonymous()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object x)
{
MessageBox.Show("Knights Warrior");
}));
}
通過lambda的方式創(chuàng)建線程:
private void DoWithLambda()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(x =>
{
MessageBox.Show("Knights Warrior");
}));
}
線程更新UI(自定義委托的方式):
private void DoWithCommon()
{
WaitCallback waitCallBack = new WaitCallback(this.InvokeMethod);
ThreadPool.QueueUserWorkItem(waitCallBack, "Knights Warrior");
}
private delegate void InvokeMethodDelegate(string name);
private void InvokeMethod(object x)
{
this.Invoke(new InvokeMethodDelegate(this.ChangeUIWithCommon), x.ToString());
}
private void ChangeUIWithCommon(string name)
{
this.lblMessage.Text = name;
}
線程更新UI(通過Action委托)
private void DoWithAction()
{
WaitCallback waitCallback = new WaitCallback(this.DoSomethingWithAction);
ThreadPool.QueueUserWorkItem(waitCallback, "Knights Warrior");
}
private void DoSomethingWithAction(object x)
{
this.Invoke(new Action<string>(this.ChangeUI), x.ToString());
}
private void ChangeUI(string message)
{
this.lblMessage.Text = message;
}
線程更新UI(通過Func委托)
private void DoWithFunc()
{
WaitCallback waitCallback = new WaitCallback(this.DoSomethingWithFunc);
ThreadPool.QueueUserWorkItem(waitCallback, "Knights Warrior");
}
private void DoSomethingWithFunc(object x)
{
Func<string, int> f = new Func<string, int>(this.GetFuncMessage);
object result = this.Invoke(f, x.ToString());
MessageBox.Show(result.ToString());
}
private int GetFuncMessage(string message)
{
this.lblMessage.Text = message;
if (message == "Knights Warrior")
{
return 1;
}
else
{
return 0;
}
}
線程更新UI(通過Predicate委托)
private void DoWithPredicate()
{
WaitCallback waitCallback = new WaitCallback(this.DoSomethingWithPredicate);
ThreadPool.QueueUserWorkItem(waitCallback, "Knights Warrior");
}
private void DoSomethingWithPredicate(object x)
{
Predicate<string> pd = new Predicate<string>(this.GetPredicateMessage);
object result = this.Invoke(pd, x);
MessageBox.Show(result.ToString());
}
private bool GetPredicateMessage(string message)
{
this.lblMessage.Text = message;
if (message == "Knights Warrior")
{
return true;
}
else
{
return false;
}
}
概念注解:
Predicate 委托
定義:public delegate bool Predicate(T obj);
表示定義一組條件并確定指定對(duì)象是否符合這些條件的方法。這個(gè)委托經(jīng)常由 Array 和 List 類的幾種方法使用,用于在集合中檢索元素。
Func 委托
定義:public delegate TResult Func(T arg);
Func():封裝一個(gè)不具有參數(shù)并返回 TResult 的類型值的方法。
Func 封裝一個(gè)具有一個(gè)參數(shù)并返回 TResult 的類型值的方法。
Action 委托
定義:public delegate void Action(T obj);
Action:封裝一個(gè)帶有兩個(gè)參數(shù)并且返回值的方法。
這三個(gè)委托經(jīng)常會(huì)用到,區(qū)分也很簡單,Predicate接受一個(gè)T的參數(shù),返回一個(gè)bool值;Func接受0到四個(gè)參數(shù),返回一個(gè)值;Action接受一到四個(gè)參數(shù),無返回值;
五,總結(jié)
這篇文章并沒有什么深度和難度,只是對(duì)多線程進(jìn)行了一下小結(jié),如果大家想了解更多,我會(huì)單獨(dú)詳細(xì)寫一些,當(dāng)然由于本人知識(shí)有限,文中錯(cuò)誤之處也敬請(qǐng)海涵!下一篇開始我們將繼續(xù)更新WPF 基礎(chǔ)到企業(yè)應(yīng)用系列索引系列文章,如果有感興趣的同仁,敬請(qǐng)關(guān)注!
NET技術(shù):閑話“多線程”,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。