c# - 在没有异步关键字的情况下声明方法返回类型 Task<int>

标签 c# async-await task

在什么情况下你会返回一个Task<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>
*/

最佳答案

当您返回 Task 时来自非 async方法?

Task<T>被概括为对 future 值(value)的 promise 。您是否从 async 产生这个 promise 关键字方法或来自其他来源(如启动的线程或 IO 回调)对调用者不感兴趣,而只是一种实现策略。这也是接口(interface)(或抽象方法定义)没有 async 的原因。关键字(async/await 是一种实现策略)。

您的代码示例

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

关于c# - 在没有异步关键字的情况下声明方法返回类型 Task<int>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54720354/

相关文章:

c# - 为什么我会收到关于隐藏基类方法的属性的警告 CS0108

python - 异步IO。如何异步调用1000个方法并在准备好后立即获取异步结果

javascript - 等待 javascript 和 graphql/node 中的 Promise

c# - 使用 async/await 卡住 UI

c# - 检查来自不同线程的异步任务的完成

windows-phone-7 - WebBrowserTask失败

c# - 在 Windows Phone 8.1 ListView 中重新排序

c# - 异步递归。我的内存到底去哪儿了?

javascript - 只有在父组件的异步方法完成后才渲染子组件

c# - 将 TabControl 附加到 MDI 父窗体而不是工具条