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

Mic*_*ett 23 c# asynchronous ctp async-await

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

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

但是,如果我需要执行另一个任务的任务,我可以将其标记为"异步"并使用"等待"吗?我试过这个:

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

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

我在这里错过了什么?

迈克尔

Ste*_*ary 18

您可能想阅读我的async/ await介绍帖子.

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

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

这背后的原因在我的描述异步"为什么关键字WORK 道"非官方的常见问题.

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我遵循这些准则:1)每个方法都不是"async",除非它需要是"async".2)如果你需要异步操作的结果,那么`await`它.3)包含`await`的所有方法必须是`async`(如果需要,将其结果包装在`Task <TResult>`中).必要时重复(2)和(3). (2认同)