簡體   English   中英

c#“任務方法”也可以是“異步”方法嗎?

[英]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 一種常見的模式是使用publicasync方法,僅在必要時才調用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.

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