劉毓,聶思兵,楊濟(jì)寧
(1.內(nèi)江師范學(xué)院計(jì)算機(jī)科學(xué)學(xué)院(人工智能學(xué)院),四川 內(nèi)江 641100;2.珠海博聞教育科技發(fā)展有限公司,廣東 珠海 519000;3.內(nèi)江職業(yè)技術(shù)學(xué)院,四川 內(nèi)江 641111)
程序執(zhí)行流的最小執(zhí)行單位,是行程中的實(shí)際運(yùn)作單位,是進(jìn)程中的實(shí)際運(yùn)作單位[1];是進(jìn)程中按順序執(zhí)行的控制流,每條線程承擔(dān)各自的任務(wù),一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程[2]。線程間通信主要通過(guò)共享內(nèi)存,上下文切換很快,資源開銷較少,但相比進(jìn)程不夠穩(wěn)定容易丟失數(shù)據(jù)。
為提高程序的可靠性,簡(jiǎn)化編程代碼,實(shí)現(xiàn)程序并發(fā)執(zhí)行線程,線程采用代碼與代碼之間的隔離技術(shù)。由此可見,合理安排線程實(shí)驗(yàn),對(duì)于C# 的實(shí)驗(yàn)有重要意義。
討論C#線程實(shí)驗(yàn),目的就是通過(guò)實(shí)驗(yàn)讓學(xué)生掌握線程的創(chuàng)建與控制,包括創(chuàng)建線程、暫停和恢復(fù)線程、終止線程、設(shè)置線程執(zhí)行的優(yōu)先級(jí),線程的同步方法。
在C#語(yǔ)言中線程(Thread)是包含在進(jìn)程中的,它位于 System.Threading 命名空間中,線程的創(chuàng)建以及執(zhí)行使用hread 類。
Thread類的實(shí)現(xiàn)方式,關(guān)鍵代碼如下:
public void TestThread()
{
Thread thread = new Thread( TestAction);
//設(shè)置屬性
thread.IsBackground = true;
thread.Name = "Test";
//啟動(dòng)線程 thread.Start();
}
private void TestAction()
{
//處理相關(guān)業(yè)務(wù)
}
主要操作步驟為:設(shè)置相關(guān)屬性new Thread(TestAction);啟動(dòng) thread.Start();處理的相關(guān)業(yè)務(wù);執(zhí)行相關(guān)業(yè)務(wù)操作等。
需要?jiǎng)?chuàng)建的線程很多,且都是比較小的線程的情況下,可以使用線程池(ThreadPool類)。ThreadPool是一個(gè)靜態(tài)方法,提供了對(duì)一個(gè)線程集合的操作,它會(huì)在線程數(shù)不足時(shí)增加線程,空閑線程數(shù)過(guò)多時(shí)釋放資源。ThreadPool 線程池實(shí)現(xiàn)的關(guān)鍵,有如下幾步:
設(shè)置相關(guān)屬性;通過(guò)線程池自動(dòng)分配線程執(zhí)行對(duì)應(yīng)的業(yè)務(wù)功能;實(shí)現(xiàn)線程處理的相關(guān)業(yè)務(wù);執(zhí)行相關(guān)業(yè)務(wù)操作等。
delegate由于需要不斷的實(shí)例化,委托類將會(huì)消耗cup 和內(nèi)存,其關(guān)鍵代碼如下:
private void TestAction()
{
//處理相關(guān)業(yè)務(wù)
}
///
///子線程回調(diào)
///
private void CallBack(IAsyncResultar)
{
}
除此之外,還有Task 實(shí)現(xiàn)多線程,Parallel實(shí)現(xiàn)多線程等方式,這里不一一贅述。
在C#線程編程實(shí)踐發(fā)現(xiàn),單線程最顯著的缺點(diǎn)是,當(dāng)一個(gè)事件發(fā)生,程序進(jìn)行一個(gè)耗時(shí)的運(yùn)算動(dòng)作時(shí),UI線程會(huì)出現(xiàn)假死現(xiàn)象,此時(shí)會(huì)無(wú)視對(duì)用戶的響應(yīng)。多個(gè)執(zhí)行流是多線程的特點(diǎn),因此為了充分提高CPU的利用率。一個(gè)程序中可以同時(shí)運(yùn)行和創(chuàng)建多個(gè)并行執(zhí)行的線程來(lái)完成各自的任務(wù)。
在多線程程序中,線程的運(yùn)行相互獨(dú)立,互不干擾,從而提高程序的效率。但使用多線程存在諸多不利因素,線程越多占用內(nèi)存也越多,線程越多協(xié)調(diào)和管理越麻煩, CPU需要花更多的時(shí)間,也存在訪問共享資源時(shí)會(huì)彼此干擾,從而導(dǎo)致對(duì)他們的控制過(guò)程太復(fù)雜。以下兩個(gè)問題也得一起注意:
利用Thread.Start()方法重新啟動(dòng)線程oThread,但顯然Abort()方法帶來(lái)的后果是不可恢復(fù)的終止線程,所以最后程序會(huì)拋出ThreadStateException異常。其關(guān)鍵內(nèi)容包括:
創(chuàng)建一個(gè)線程,使之執(zhí)行Beta方法 ,該方法只是通知CPU此線程可以被執(zhí)行,但具體執(zhí)行時(shí)機(jī)則由CPU自行決定。
線程的優(yōu)先級(jí)設(shè)置應(yīng)滿足以下原則:
1)當(dāng)線程之間同時(shí)需要CPU時(shí),CPU按線程的優(yōu)先級(jí)給予服務(wù)。
2)C#設(shè)計(jì)中,在創(chuàng)建線程時(shí),可以設(shè)置5個(gè)不同的線程的優(yōu)先級(jí),不指定優(yōu)先級(jí),則系統(tǒng)為默認(rèn)值ThreadPriority.Normal。
根據(jù)用戶的響應(yīng)輕重緩急,設(shè)置相應(yīng)的線程的優(yōu)先級(jí),同時(shí)CPU會(huì)將更多的時(shí)間片分給優(yōu)先級(jí)高的線程,在相同任務(wù)量的前提下,高優(yōu)先級(jí)線程將會(huì)較快地完成任務(wù)。
多線程編程應(yīng)用廣泛,主要有幾個(gè)方面:
1)即時(shí)響應(yīng),后臺(tái)線程完成特定操作。
2)多個(gè)線程參與,完成同類任務(wù),提高并發(fā)性能。
3)一個(gè)任務(wù)可以有多個(gè)獨(dú)立的步驟,多個(gè)線程可以并發(fā)執(zhí)行各子任務(wù),以用來(lái)提高任務(wù)處理效率,下面通過(guò)兩個(gè)例子予以說(shuō)明。
a)進(jìn)度條
圖1 系統(tǒng)方框圖
分析:頁(yè)面動(dòng)態(tài)刷新,在主頁(yè)面正常操作前提下,用后臺(tái)線程來(lái)實(shí)現(xiàn)進(jìn)度條。
首先,創(chuàng)建Winform頁(yè)面,然后拖入進(jìn)度條控件,篇幅關(guān)系,相關(guān)代碼從略。
b)網(wǎng)絡(luò)扒蟲
獲取網(wǎng)絡(luò)資源,網(wǎng)絡(luò)搜索功能實(shí)現(xiàn),都利用了扒蟲程序思想。一般情況下,扒蟲程序耗時(shí)大,如果使用多線程編程,將節(jié)約許多時(shí)間。篇幅關(guān)系,相關(guān)代碼從略。
前面就C#實(shí)現(xiàn)線程的常用方式,C#線程的實(shí)驗(yàn)的注意事項(xiàng),C#多線程的典型應(yīng)用實(shí)驗(yàn)做了初步的討論,關(guān)于C#線程實(shí)驗(yàn)注意的問題還很多,由于篇幅所限,這里不一一贅述。
文中的部分案例來(lái)自網(wǎng)絡(luò),由于出處較多,在此一并向作者致謝!