C 學習筆記 非同步操作

2021-07-09 09:23:11 字數 1985 閱讀 1423

預設情況下我們的**都是同步操作。這種情況下,所有的操作都在同乙個執行緒中,如果遇到需要長時間執行的操作或者是乙個io操作,那麼**可能會阻塞比較長的時間。在阻塞的這段時間裡,無法進行其他工作,這是很不好的。

這裡是乙個同步操作的例子。乙個操作需要大約5秒時間,然後另乙個操作好過去前乙個操作的結果並顯示。在這5秒鐘時間裡,執行緒會被阻塞,無法進行任何工作。

private

static

string

dosomethinglong()

private

static

void

dosomethingelse(string str)

public

static

void

dosynchronouswork()

.net支援三種型別的非同步操作方式,第一種是非同步模式。實現這種模式的類會定義類似begin***和end***的方法。現在這種方式已經不怎麼使用了。第二種是基於事件的非同步模式,實現這種模式的類會定義乙個事件,該事件會在非同步呼叫完成之後被觸發,我們要做的事情就是向這個事件註冊乙個監聽程式即可。第三種就是現在最新的基於任務的非同步模式,這種方式利用了類庫中已有的task類和async/await關鍵字來實現,現在主要就是使用這種模式。

要使用基於任務的非同步模式,首先需要乙個返回task的方法。

private

static task dosomethinglongasync()

返回task的方法被認為是可等待的。這樣的方法可以使用await關鍵字等待。如果乙個方法體中使用了await關鍵字,那麼這個方法宣告就必須新增async關鍵字。新增了async關鍵字的方法就是非同步方法。非同步方法在執行的時候遇到await關鍵字處,不會被阻塞,而是直接返回,等到await出的**執行完畢,乙個執行緒就會進入這裡繼續執行。這裡所有的額外行為全部由編譯器實現。

public

static

async task doworkuseasyncandawait()

上面這個方法工作起來就像下面一樣:

public static void doworkasynchronouslywithtask()

一般情況下使用task的時候如果丟擲異常,task會丟擲乙個aggregateexception異常,內部的innerexception和innerexceptions屬性會封裝了實際丟擲的異常。而使用非同步方法的時候,為了提供與同步方法相似的程式設計體驗,當丟擲異常的時候會直接丟擲原始異常而不是aggregateexception異常。

首先先來定義乙個返回task的會丟擲異常的方法。

private

static task dosomethinglongwithexception()

; return task.run(action);

}

然後非同步等待這個方法,並處理可能丟擲的異常:

public

static

async task workwithsomethingthrowable()

"); }

catch (invalidoperationexception ex)

");}

console.writeline();

}

如果非同步方法丟擲了異常,那麼代表這個非同步方法的task物件會因為異常而結束,等待這個非同步方法的**就會獲得該異常。但是如果丟擲異常的非同步方法返回void,呼叫者就無法捕獲該異常。這個時候,編譯器生成的**會捕捉它,並在呼叫者的同步上下文上重新丟擲異常,這會導致整個程式結束。所以,盡量使用返回task的非同步方法。

C 非同步筆記

認真地看了一些c 5裡面 await async的相關 寫法,給自己做一些特別提醒。終於明白 await 應該是等待完成再執行後面的 雖然等待的方法正在執行,但是ui不會卡住而已。async await理論上講還是c 語言層次的語法糖,在il層面不涉及到新的指令 但它的實現並非 啟動乙個新執行緒去更...

ES6學習筆記(四) 非同步操作

pending resolved rejected var promis new promise function resolve,reject error err promis.then function res catch function err 鏈式呼叫,狀態變為resolve 如果把下一步...

C 非同步操作 async await

private void btnolddownload click object sender,eventargs e lbmessage.text private void oldasyncdownload click object sender,eventargs e private void ...