溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C#中異步調(diào)用的原理是什么

發(fā)布時(shí)間:2021-06-24 16:28:01 來源:億速云 閱讀:306 作者:Leah 欄目:編程語言

本篇文章為大家展示了C#中異步調(diào)用的原理是什么,內(nèi)容簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

C#異步調(diào)用是什么呢?具體的內(nèi)容又是什么呢?讓我們開始C#異步調(diào)用的學(xué)習(xí)吧

計(jì)算機(jī)中有些處理比較耗時(shí)。調(diào)用這種處理代碼時(shí),調(diào)用方如果站在那里苦苦等待,會(huì)嚴(yán)重影響程序性能。例如,某個(gè)程序啟動(dòng)后如果需要打開文件讀出其中的數(shù)據(jù),再根據(jù)這些數(shù)據(jù)進(jìn)行一系列初始化處理,程序主窗口將遲遲不能顯示,讓用戶感到這個(gè)程序怎么等半天也不出來,太差勁了。借助C#異步調(diào)用可以把問題輕松化解:把整個(gè)初始化處理放進(jìn)一個(gè)單獨(dú)線程,主線程啟動(dòng)此線程后接著往下走,讓主窗口瞬間顯示出來。等用戶盯著窗口犯呆時(shí),初始化處理就在背后悄悄完成了。程序開始穩(wěn)定運(yùn)行以后,還可以繼續(xù)使用這種技巧改善人機(jī)交互的瞬時(shí)反應(yīng)。用戶點(diǎn)擊鼠標(biāo)時(shí),所激發(fā)的操作如果較費(fèi)時(shí),再點(diǎn)擊鼠標(biāo)將不會(huì)立即反應(yīng),整個(gè)程序顯得很沉重。借助C#異步調(diào)用處理費(fèi)時(shí)的操作,讓主線程隨時(shí)恭候下一條消息,用戶點(diǎn)擊鼠標(biāo)時(shí)感到輕松快捷,肯定會(huì)對(duì)軟件產(chǎn)生好感。

C#異步調(diào)用用來處理從外部輸入的數(shù)據(jù)特別有效。假如計(jì)算機(jī)需要從一臺(tái)低速設(shè)備索取數(shù)據(jù),然后是一段冗長的數(shù)據(jù)處理過程,采用同步調(diào)用顯然很不合算:計(jì)算機(jī)先向外部設(shè)備發(fā)出請(qǐng)求,然后等待數(shù)據(jù)輸入;而外部設(shè)備向計(jì)算機(jī)發(fā)送數(shù)據(jù)后,也要等待計(jì)算機(jī)完成數(shù)據(jù)處理后再發(fā)出下一條數(shù)據(jù)請(qǐng)求。雙方都有一段等待期,拉長了整個(gè)處理過程。其實(shí),計(jì)算機(jī)可以在處理數(shù)據(jù)之前先發(fā)出下一條數(shù)據(jù)請(qǐng)求,然后立即去處理數(shù)據(jù)。如果數(shù)據(jù)處理比數(shù)據(jù)采集快,要等待的只有計(jì)算機(jī),外部設(shè)備可以連續(xù)不停地采集數(shù)據(jù)。如果計(jì)算機(jī)同時(shí)連接多臺(tái)輸入設(shè)備,可以輪流向各臺(tái)設(shè)備發(fā)出數(shù)據(jù)請(qǐng)求,并隨時(shí)處理每臺(tái)設(shè)備發(fā)來的數(shù)據(jù),整個(gè)系統(tǒng)可以保持連續(xù)高速運(yùn)轉(zhuǎn)。編程的關(guān)鍵是把數(shù)據(jù)索取代碼和數(shù)據(jù)處理代碼分別歸屬兩個(gè)不同的線程。數(shù)據(jù)處理代碼調(diào)用一個(gè)數(shù)據(jù)請(qǐng)求異步函數(shù),然后徑自處理手頭的數(shù)據(jù)。待下一組數(shù)據(jù)到來后,數(shù)據(jù)處理線程將收到通知,結(jié)束 wait 狀態(tài),發(fā)出下一條數(shù)據(jù)請(qǐng)求,然后繼續(xù)處理數(shù)據(jù)。

C#異步調(diào)用時(shí),調(diào)用方不等被調(diào)方返回結(jié)果就轉(zhuǎn)身離去,因此必須有一種機(jī)制讓被調(diào)方有了結(jié)果時(shí)能通知調(diào)用方。在同一進(jìn)程中有很多手段可以利用,筆者常用的手段是回調(diào)、event 對(duì)象和消息。

回調(diào)方式很簡單:調(diào)用異步函數(shù)時(shí)在參數(shù)中放入一個(gè)函數(shù)地址,異步函數(shù)保存此地址,待有了結(jié)果后回調(diào)此函數(shù)便可以向調(diào)用方發(fā)出通知。如果把異步函數(shù)包裝進(jìn)一個(gè)對(duì)象中,可以用事件取代回調(diào)函數(shù)地址,通過事件處理例程向調(diào)用方發(fā)通知。

event 是 windows 系統(tǒng)提供的一個(gè)常用同步對(duì)象,以在異步處理中對(duì)齊不同線程之間的步點(diǎn)。如果調(diào)用方暫時(shí)無事可做,可以調(diào)用 wait 函數(shù)等在那里,此時(shí) event 處于 nonsignaled 狀態(tài)。當(dāng)被調(diào)方出來結(jié)果之后,把 event 對(duì)象置于 signaled 狀態(tài),wait 函數(shù)便自動(dòng)結(jié)束等待,使調(diào)用方重新動(dòng)作起來,從被調(diào)方取出處理結(jié)果。這種方式比回調(diào)方式要復(fù)雜一些,速度也相對(duì)較慢,但有很大的靈活性,可以搞出很多花樣以適應(yīng)比較復(fù)雜的處理系統(tǒng)。

借助 windows 消息發(fā)通知是個(gè)不錯(cuò)的選擇,既簡單又安全。程序中定義一個(gè)用戶消息,并由調(diào)用方準(zhǔn)備好消息處理例程。被調(diào)方出來結(jié)果之后立即向調(diào)用方發(fā)送此消息,并通過 wparam 和 lparam 這兩個(gè)參數(shù)傳送結(jié)果。消息總是與窗口 handle 關(guān)聯(lián),因此調(diào)用方必須借助一個(gè)窗口才能接收消息,這是其不方便之處。另外,通過消息聯(lián)絡(luò)會(huì)影響速度,需要高速處理時(shí)回調(diào)方式更有優(yōu)勢(shì)。

如果調(diào)用方和被調(diào)方分屬兩個(gè)不同的進(jìn)程,由于內(nèi)存空間的隔閡,一般是采用 windows 消息發(fā)通知比較簡單可靠,被調(diào)方可以借助消息本身向調(diào)用方傳送數(shù)據(jù)。event 對(duì)象也可以通過名稱在不同進(jìn)程間共享,但只能發(fā)通知,本身無法傳送數(shù)據(jù),需要借助 windows 消息和 filemapping 等內(nèi)存共享手段或借助  mailslot 和 pipe 等通信手段。

C#異步調(diào)用原理并不復(fù)雜,但實(shí)際使用時(shí)容易出莫名其妙的問題,特別是不同線程共享代碼或共享數(shù)據(jù)時(shí)容易出問題,編程時(shí)需要時(shí)時(shí)注意是否存在這樣的共享,并通過各種狀態(tài)標(biāo)志避免沖突。windows 系統(tǒng)提供的 mutex 對(duì)象用在這里特別方便。mutex 同一時(shí)刻只能有一個(gè)管轄者。一個(gè)線程放棄管轄權(quán)后,另一線程才能接管。當(dāng)某線程執(zhí)行到敏感區(qū)之前先接管 mutex,使其他線程被 wait 函數(shù)堵在身后;脫離敏感區(qū)之后立即放棄管轄權(quán),使 wait 函數(shù)結(jié)束等待,另一個(gè)線程便有機(jī)會(huì)光臨此敏感區(qū)。這樣就可以有效避免多個(gè)線程進(jìn)入同一敏感區(qū)。

由于C#異步調(diào)用容易出問題,要設(shè)計(jì)一個(gè)安全高效的編程方案需要比較多的設(shè)計(jì)經(jīng)驗(yàn),所以***不要濫用C#異步調(diào)用。同步調(diào)用畢竟讓人更舒服些:不管程序走到哪里,只要死盯著移動(dòng)點(diǎn)就能心中有數(shù),不至于象C#異步調(diào)用那樣,總有一種四面受敵、惶惶不安的感覺。必要時(shí)甚至可以把異步函數(shù)轉(zhuǎn)換為同步函數(shù)。方法很簡單:調(diào)用異步函數(shù)后馬上調(diào)用 wait 函數(shù)等在那里,待異步函數(shù)返回結(jié)果后再繼續(xù)往下走。

上述內(nèi)容就是C#中異步調(diào)用的原理是什么,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI