這里有兩個方法
public override Task<ClassA> GetClassA()
{
return Task.Run(()=>{
ClassA a = new ClassA();
return a;
});
}
public override async Task<ClassA> GetClassA()
{
return await Task.Run(()=>{
ClassA a = new ClassA();
return a;
});
}
這2個方法除了寫法上不同 有其他區別嗎?
uj5u.com熱心網友回復:
加了 async和await 的 回傳的Task的Result是 一個new好的ClassA物件 因為await 會等Task.Run里的內容執行完而沒加async和await的 回傳的Task的Result是null 因為在函式執行結束的時候Task.Run里的內容還沒開始跑
uj5u.com熱心網友回復:
asyn 異步,用腦袋想不明白的話,可以到MSDN坐坐uj5u.com熱心網友回復:
這個要分開說。加不加 async,是一樣的。
但是加了async后,加不加await。是不一樣的。
uj5u.com熱心網友回復:
async只是告知,這可能是一個異步。當async+await,才是異步。
uj5u.com熱心網友回復:
實際上更貼切地寫法是public override Task<ClassA> GetClassA()
{
ClassA a = new ClassA();
return Task.FromResult(a);
}
從方便清晰貼切的語意角度看,async 顯然是讓特定的一些回傳 Task<> 的方法更易讀更貼切的一種“語法糖”。
uj5u.com熱心網友回復:
例如異步方法public static async Task t()
{
var web = new WebClient();
var r = await web.UploadDataTaskAsync("http://localhost:12341", Encoding.UTF8.GetBytes("spsp1234"));
var s = Encoding.UTF8.GetString(r);
Debug.Assert(s.StartsWith("path 長度="));
}
這里因為有 await,以順序陳述句的語法來演繹并發異步操作之實,顯然 async/await 少一層 Task 封裝,比較清晰。
一個大方法中可能有許多 await,甚至是在回圈結構中使用await。而你舉出的例子“刻意地”是可以不用 await 的例子,其實這類方法不需要定義 Task 作為函式回傳值,或者可以寫成
public override Task<ClassA> GetClassA()
{
await Tasks.Yield();
ClassA a = new ClassA();
return a;
}
如果你在本不存在的問題上制造繁瑣,那么其實就煩惱了。
uj5u.com熱心網友回復:
上面少了一個 async,應該改為:public override async Task<ClassA> GetClassA()
{
await Tasks.Yield();
ClassA a = new ClassA();
return a;
}
總之,你原本可以定義一個
public override ClassA GetClassA()回傳型別的方法,你現在卻定義為 Task<ClassA> 作為函式回傳值這本身應該算是增加了一層繁瑣。當然,為了實作某種介面規格而回傳 Task,那么你可以使用 await Tasks.Yield。實際上可以不考慮 Task.Run。
再次強調一下,沒有必要使用 Task.Run(......) 的時候,其實使用 async/await 語法更清爽、貼切。
uj5u.com熱心網友回復:
+1
至于樓主問題,兩個方法在邏輯上一樣,但運行上有區別的。
原因是:
一、await會帶來背景關系切換;
二、await需要捕獲當前的"運行背景關系"(ExecutionContext),以便隨后重施。該捕獲保證了異步運行的代碼,可以有相同的LogicalCallContext,SecurityContext等,并支持回到當前SynchronizationContext等,但捕獲也帶來了稍許的額外開銷。
因此,無需顧慮使用async await。但是,如果是樓主的方法一,就最好不加await。
網上有roslyn請求,希望編譯器能自動偵測尾部await呼叫,并自動優化為方法一寫法,但目前該請求還處于‘開放’狀態(https://github.com/dotnet/roslyn/issues/1981)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/21169.html
標籤:C#
