声明方法返回类型 Task<int> 没有 async 关键字

Bac*_*ave 2 c# task async-await

在什么情况下你会返回 aTask<T>而不async在方法签名中使用?

我在下面的代码中有这样一个方法,但我无法理解发生了什么。

为什么我下面的示例代码没有执行任何await语句?IE。为什么Console.WriteLine("4)");Console.WriteLine("3)");return x;从来没有得到执行?

class Program
    {
        static void Main(string[] args)
        {
            TestAsync testAsync = new TestAsync();
            testAsync.Run();

            Console.Read();
        }
    }

    public class TestAsync
    {
        public async void Run()
        {
            Task<int> resultTask = GetInt();
            Console.WriteLine("2)");
            int x = await resultTask;
            Console.WriteLine("4)");
        }
        public async Task<int> GetInt()
        {
            Task<int> GetIntAfterLongWaitTask = GetIntAfterLongWait();
            Console.WriteLine("1)");
            int x = await GetIntAfterLongWaitTask;
            Console.WriteLine("3)");
            return x;
        }

        public Task<int> GetIntAfterLongWait()
        {            
            Task.Run(() =>
            {
                for (int i = 0; i < 500000000; i++)
                {
                    if (i % 10000000 == 0)
                    {
                        Console.WriteLine(i);
                    }
                }
            });

            Console.WriteLine("Returning 23");
            return new Task<int>(() => 23);
        }
    }

/*
Output is:
Returning 23
1)
2)
<list of ints>
*/
Run Code Online (Sandbox Code Playgroud)

Tho*_*mas 5

当您Task从非async方法返回 a 时?

Task<T>概括地说是对未来价值的承诺。无论您是从关键字方法还是从其他来源(如已启动的线程或 IO 回调)生成此承诺,调用者都不感兴趣,而只是实现策略。这也是为什么接口(或抽象方法定义)根本没有关键字的原因(/是一种实现策略)。asyncasyncasyncawait

您的代码示例

  • 问题 1:您的方法GetIntAfterLongWait在两个方面存在缺陷。第一个实例化Task被实例化并卸载到一个线程,但结果永远不会被提取(所以永远不会等待......并且永远不会延迟任何东西)。
  • 问题 2:第二个任务(您在 中返回的任务GetIntAfterLongWait)已创建(由具有要执行的方法的构造函数)但未启动 ( Task.Start())。其他更简单的方法是 static Task.Runor(在这种情况下)Task.FromResult。任务(或承诺)永远不会交付结果,因为构造函数中的功能块永远不会执行。
  • 问题 3:该Main方法不等待返回任务的结果(通过awaitTask.Wait()Task.Result.