[英]c# Can a “task method” also be an “async” method?
我試圖抓住新的異步CTP的東西,我可能在這里迷惑自己..我可以有這個“任務方法”,沒有問題:
public static Task<String> LongTaskAAsync() {
return Task.Run(() => {
return("AAA");
});
}
但是,如果我需要執行另一個任務的任務,我可以將其標記為“異步”並使用“等待”嗎? 我試過這個:
public async static Task<String> LongTaskAAsync() {
await Task.Delay(2000);
return Task.Run(() => {
return("AAA");
});
}
但后來神秘地得到了這個編譯錯誤:由於這是一個異步方法,返回表達式必須是'string'類型而不是Task<string>
我在這里錯過了什么?
邁克爾
您可能想要閱讀我的async
/ await
介紹帖子 。
async
方法的返回值包含在Task<TResult>
。 同樣, await
解包這些返回值:
public static async Task<String> LongTaskAAsync() {
await Task.Delay(2000);
return await Task.Run(() => {
return("AAA");
});
}
這背后的原因在我的描述異步“為什么關鍵字工作方式 ”非官方的常見問題 。
PS你也可以使用Task.FromResult
進行這樣的簡單測試。
編輯:如果你想創建並返回Task
對象本身,則該方法不應該是async
。 一種常見的模式是使用public
非async
方法,僅在必要時才調用async
部分。
例如,某種異步緩存 - 如果對象在緩存中,則立即返回; 否則,異步創建它,將其添加到緩存中並返回它(這是示例代碼 - 不是線程安全的):
public static Task<MyClass> GetAsync(int key)
{
if (cache.Contains(key))
return Task.FromResult(cache[key]);
return CreateAndAddAsync(key);
}
private static async Task<MyClass> CreateAndAddAsync(int key)
{
var result = await CreateAsync(key);
cache.Add(key, result);
return result;
}
“任務方法”也可以是“異步”方法嗎?
是的,它可以通過簡單地將方法簽名更改為public async static Task<Task<String>> LongTaskAAsync()
因為它將返回它。
如果使用async
關鍵字,則運行時將包裝返回到任務的類型,以啟用異步。 假設您返回一個string
,運行時會將其包裝到Task<string>
。 int
將轉到Task<int>
, Task<string>
將轉到Task<Task<string>>
。 請參閱此控制台應用以清除:
public class Program
{
public static void Main(string[] args)
{
// start the main procedure asynchron
Task.Run(() => DoIt()).Wait();
}
// for async support since the static main method can't be async
public static async void DoIt()
{
Program p = new Program();
// use the methods
string s = await p.GetString();
int i = await p.GetInt();
Task<string> tsk = await p.GetTaskOfString();
// just to prove the task works:
// C# 5
string resultFromReturnedTask = await tsk;
// C# 4
string resultFromReturnedTask2 = tsk.Result;
}
public async Task<string> GetString()
{
return "string";
}
public async Task<int> GetInt()
{
return 6;
}
public async Task<Task<string>> GetTaskOfString()
{
return Task.Run(() => "string");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.