簡體   English   中英

在Task中調用異步方法

[英]Calling async method inside a Task

假設我有一個異步方法,例如:

public async Task<int> HeavyWork()
{
    return Task.Run( () => { //some heavy work } );
}

假設我通過將此任務添加到隊列中將其放置在另一個任務中:

...
QueueTask(new Task( () => { HeavyWork(); } ));
...

假設方法QueueTask只是接收一個任務並啟動它,然后等待它完成,然后繼續執行下一個任務...啟動其中包含“ HeavyWork()”的任務...它將立即返回異步?

asyncawait關鍵字協同工作,可以使方法在完成之前返回,然后在以后的時間繼續執行。

由於您的問題中幾乎沒有顯示任何實際代碼,因此無法准確解釋您的情況會發生什么。 從字面上看,您的HeavyWork()方法根本不需要async ,因為其中沒有使用await

換句話說, async只允許await 它根本不影響該方法的行為。 如果您從未在該方法中使用過await ,則該方法將同步運行,直到完成其工作后才會返回。

在這種情況下,您將Task對象添加到隊列中,隊列啟動任務,任務調用匿名方法,該方法又調用HeavyWork() ,並且直到HeavyWork()方法返回時任務才完成,從而允許返回的匿名方法。

那不是很有趣,所以讓我們假設在HeavyWork()某個地方,您實際上確實使用了await 在那種情況下, HeavyWork()方法將在完成執行之前, await發生時返回(即,在await任何事物返回其等待對象(通常是Task對象)之后,以及await之后的任何東西之前) )。

就您排隊的Task而言, 就是對HeavyWork()的調用完成。 因此,排隊的任務將在HeavyWork()方法實際完成執行之前完成。 請注意,這並不一定立即生效; 在首次await之前的任何代碼都將在HeavyWork()返回之前執行。

請注意,在第二種情況下,如果您想知道HeavyWork()方法何時完成,則需要以某種方式觀察返回的Task 通常,這可以通過awaitTask.WhenAll() (用於Task對象的集合)或類似的機制來完成。

一種可能的方法是,由於您的任務隊列是(如您所說的)同步等待每個任務完成(不一定是最佳設計,但讓我們假設目前有充分的理由在這里),因此您可以讓它檢查每個任務在嘗試啟動之前,只有在尚未啟動時才啟動它(嘗試啟動已經啟動的任務將導致拋出異常)。

在這種情況下,您可以將HeavyWork()方法本身的返回值傳遞給隊列:

QueueTask(HeavyWork());

然后, HeavyWork()會一直執行到第一次await (大概是相對較快的,因為使方法async的全部原因是讓您將長時間運行的工作移到異步位置進行),然后將返回Task對象代表整個方法的工作。

在使該特定Task對象出隊時,該隊列將注意到該隊列已經開始,只需要等待它完成即可。 HeavyWork()方法最終完成其所有工作並且有可用結果時,該隊列將看到等待完成並繼續執行,就像已將其傳遞給某個同步方法周圍的Task包裝器一樣。


請注意,以上所有內容都必須是含糊且假設的。 考慮到原始問題的含糊,無法提供具體的建議。 但是,我希望這有助於闡明asyncawait如何協同工作,尤其是在您描述的模糊情況下如何工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM