简体   繁体   English

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

[英]c# Can a “task method” also be an “async” method?

I'm trying to get the hand of the new async CTP stuff and I'm probably confusing myself here.. I can have this "task method", with no problem: 我试图抓住新的异步CTP的东西,我可能在这里迷惑自己..我可以有这个“任务方法”,没有问题:

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

But what if I need the task to execute another task, can I mark it as "async" and use "await"? 但是,如果我需要执行另一个任务的任务,我可以将其标记为“异步”并使用“等待”吗? I tried this: 我试过这个:

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

But then mysteriously get this compiler error: Since this is an async method, the return expression must be of type 'string' rather than Task<string> 但后来神秘地得到了这个编译错误:由于这是一个异步方法,返回表达式必须是'string'类型而不是Task<string>

What am I missing here? 我在这里错过了什么?

Michael 迈克尔

You may want to read my async / await intro post . 您可能想要阅读我的async / await介绍帖子

Return values from async methods are wrapped in a Task<TResult> . async方法的返回值包含在Task<TResult> Likewise, await unwraps those return values: 同样, await解包这些返回值:

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

The reasoning behind this is described in my Async "Why Do the Keywords Work That Way" Unofficial FAQ . 这背后的原因在我的描述异步“为什么关键字工作方式 ”非官方的常见问题

PS You can also use Task.FromResult for simple tests like this. PS你也可以使用Task.FromResult进行这样的简单测试。

Edit: If you want to create and return the Task object itself, then the method should not be async . 编辑:如果你想创建并返回Task对象本身,则该方法应该是async One somewhat common pattern is to have a public non- async method that calls the async portion only if necessary. 一种常见的模式是使用publicasync方法,仅在必要时才调用async部分。

For example, some kind of asynchronous cache - if the object is in the cache, then return it immediately; 例如,某种异步缓存 - 如果对象在缓存中,则立即返回; otherwise, asynchronously create it, add it to the cache, and return it (this is example code - not thread-safe): 否则,异步创建它,将其添加到缓存中并返回它(这是示例代码 - 不是线程安全的):

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;
}

Can a “task method” also be an “async” method? “任务方法”也可以是“异步”方法吗?

Yes it can be, by simply changing the method signature to public async static Task<Task<String>> LongTaskAAsync() since that is, what it will return. 是的,它可以通过简单地将方法签名更改为public async static Task<Task<String>> LongTaskAAsync()因为它将返回它。

If you use the async keyword, the runtime will wrap the type you return into a task, to enable asynchronousness. 如果使用async关键字,则运行时将包装返回到任务的类型,以启用异步。 Say if you return a string , the runtime will wrap that into a Task<string> . 假设您返回一个string ,运行时会将其包装到Task<string> int will go Task<int> and Task<string> will go Task<Task<string>> . int将转到Task<int>Task<string>将转到Task<Task<string>> See this console app to clearify: 请参阅此控制台应用以清除:

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