C 中對非同步方法及非同步lambda表示式的一些處理

2021-08-20 04:05:12 字數 2476 閱讀 3915

這篇文章的目的並不是系統地介紹c#中的awaitasync關鍵字,而是針對我遇到的一些問題進行記錄。

c#中可以用async標識方法,表示這個方法是非同步的。非同步方法的返回值必須是voidtask或者task。例如:

public

static

async taskmethod

(int i)

我們可以用async修飾lambda表示式,標識這個表示式為非同步。

func> lambda = async () =>

};

可以看到,用async修飾以後,返回值也變為task

async標記只是針對方法內部,外部只關心返回值型別。

非同步方法在遇到await關鍵字之後就會返回。例如下面的**:

private

static stopwatch stopwatch;

static

void main(string args)

");}

public

static

async task methodasync()

"); await task.delay(1000);

console.writeline($"end of method: ");

}

methodasync()方法會在遇到await時返回。於是就有了如下輸出:

enter method.

method

will

return:

542main: 544

我們可以用task.run(action action)來啟動乙個任務。

static

void main(string args)

");}

其中methodasync就是上面定義的方法。

可以推測,methodasync執行到第乙個await就會返回。wait()方法也會執行完畢。整段程式執行500多毫秒就應該結束。

讓我們執行一下。

enter method.

method

will

return:

544end

ofmethod:

1546

main: 1547

奇怪,methodasync返回不久,整個程式就應該結束才是,為什麼等待了一秒多,直到methodasync全部執行完?

原來,task.run那裡實際呼叫的是task.run(funcfunction)這個過載。這個過載返回的task物件,我們在呼叫其wait()成員方法時會等待function返回的task物件執行結束。我認為應該是為了方便這種情況。

await task.run(async () =>

});

在這段**中,正是由於呼叫的是task.run(funcfunction)這個過載,才保證了請求完成後才會繼續執行後面的**。

system.threading.tasks.parallel類提供了非常方便的併發執行迴圈的方法。

parallel.for(0, 10, i => console.writeline(i));
輸出

026

4589

731

再試試

parallel.for(0, 10, async i =>

);

輸出

是的,輸出沒有任何內容。

原因是,paralleltask不一樣,它並不會等待返回的task,而是在方法返回後就結束。

所以,如果想確保非同步方法完全完成,必須改為同步。

parallel.for(0, 10, i =>

);

輸出

846

2017

539

C 非同步方法呼叫

using system using system.collections.generic using system.componentmodel using system.data using system.drawing using system.linq using system.text u...

c 方法轉非同步例子

using system using system.collections.generic using system.linq using system.text using system.threading using system.threading.tasks namespace 亞信電子商務...

C 中的非同步陷阱

c 中的非同步陷阱 原文 有時候,理解一種語言中的缺陷的最好方式是檢視另一種語言如何防止這些缺陷發生。real world functional programming 注 該書已由清華大學出版社引進,中文名 c 與f 程式設計實踐 的作者tomas petricek討論了非同步c 中常見的7項錯誤...