我很難理解將異步作業卸載到 Task.Run() 的好處。之前有很多關于異步作業被卸載到任務的問題,但我從未見過,對我來說最大的謎團是什么,正在被解決。
考慮兩個選項:
- 選項1:
var t1= Task.Run( async() => { await AsyncRead(); });
- 選項2:
var t2= Task.Run( () => { Read(); });
使用第二個選項,作業已經被卸載到一個單獨的執行緒,然后在呼叫 t2 的程式范圍內已經獲得了異步性。現在,雖然第一個選項中正在完成的作業被宣告并實作為異步,但它本質上是讓已經異步運行的代碼也可以異步運行。從中得到什么好處?調度程式或管理這些任務執行緒的任何東西可以讀入嗎?然后也許讓那個等待執行緒在另一個任務上做一些作業?如果是這種情況,我沒有在任何專家博客文章或互聯網上的相關頁面中看到它。
uj5u.com熱心網友回復:
在您的示例中,如果f1()和f2()是異步的(因為它們回傳任務),那么 async 關鍵字將允許您等待Task.Run().
您的問題類似于“為什么要將任何方法標記為異步”……因為您想在其中運行異步代碼。或者更具體地說,您希望編譯器構建狀態機來處理“等待”異步操作完成。
uj5u.com熱心網友回復:
使用第二個選項,作業已經被卸載到一個單獨的執行緒,然后在呼叫 t2 的程式范圍內已經獲得了異步性。
Task.Run不會使某些東西異步。它確實允許您在執行緒池執行緒上運行同步代碼(從而阻塞執行緒池執行緒而不是其他執行緒),但我不會說它“使其異步”。代碼仍在同步阻塞執行緒。
現在,雖然第一個選項中正在完成的作業被宣告并實作為異步,但它本質上是讓已經異步運行的代碼也異步運行自身。從中得到什么好處?調度程式或管理這些任務執行緒的任何東西可以讀入嗎?然后也許讓那個等待執行緒在另一個任務上做一些作業?
執行緒沒有await。方法await。當一個執行緒正在運行一個方法并命中一個await時,該方法被暫停,該方法回傳給它的呼叫者,并且執行緒繼續執行。在委托傳遞給 的情況下Task.Run,await將導致方法回傳 - 到執行緒池,從而將執行緒回傳到執行緒池。當awaited 任務完成后,將使用執行緒池中的一個執行緒繼續執行該方法;這可能是同一個執行緒或完全不同的執行緒。
我的博客上有更多關于如何await作業的資訊。
如果是這種情況,我沒有在任何專家博客文章或互聯網上的相關頁面中看到它。
我有一個關于Task.Run禮儀的系列。本質上,Task.Run主要用于從 GUI 應用程式中的 UI 執行緒卸載同步或 CPU 密集型作業。如果您想快速開始處理某些內容并回圈回傳并抓取下一個要處理的內容,它有時在服務器端場景中也很有用。還有一些其他用例,但很少見。
這些原因都適用于異步 API。有時 API看起來是異步的,但實際上并非如此。或者有些方法是異步的,但它們首先進行了大量的同步作業,因此Task.Run在某些情況下,即使使用異步代碼,a 仍然是可取的。
uj5u.com熱心網友回復:
我不確定我的問題是否正確。專注于“它本質上是讓已經異步運行的代碼也異步運行”:
盡管在 中運行異步代碼似乎毫無意義Task.Run,但在某些情況下這可能是必要的。異步方法總是同步運行,直到第一次“真正的”異步呼叫發生。一個很好的例子是使用backgroundservices。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/476105.html
下一篇:如何通過字典中的不同級別
