c#“任务方法”也可以是“异步”方法吗?

时间:2012-07-30 00:03:04

标签: c# asynchronous async-await ctp

我正试图抓住新的异步CTP的东西,我可能在这里迷惑自己.. 我可以有这个“任务方法”,没有问题:

    public static Task<String> LongTaskAAsync() {
        return Task.Run(() => {
            return("AAA");
            });
        }

但是如果我需要执行另一个任务的任务,我可以将其标记为“async”并使用“await”吗?我试过这个:

public async static Task<String> LongTaskAAsync() {
        await Task.Delay(2000);
        return Task.Run(() => {
            return("AAA");
            });
        }

然后神秘地得到这个编译错误:由于这是一个异步方法,返回表达式必须是'string'类型而不是Task<string>

我在这里缺少什么?

迈克尔

2 个答案:

答案 0 :(得分:18)

您可能需要阅读我的async/await intro post

async方法的返回值包含在Task<TResult>中。同样,await会解包这些返回值:

public static async Task<String> LongTaskAAsync() {
  await Task.Delay(2000);
  return await Task.Run(() => {
    return("AAA");
  });
}

我的Async "Why Do the Keywords Work That Way" Unofficial FAQ中描述了这背后的原因。

P.S。您也可以使用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;
}

答案 1 :(得分:2)

  

“任务方法”也可以是“异步”方法吗?

是的,只需将方法签名更改为public async static Task<Task<String>> LongTaskAAsync()即可,因为它会返回。

如果使用async关键字,运行时将包装返回到任务的类型,以启用异步。假设您返回string,运行时会将其包装到Task<string>中。 intTask<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"); } } 。{{1}}请参阅此控制台应用以清除:

{{1}}