等待后的文本无法在异步void方法中打印出来

时间:2016-05-16 06:01:22

标签: c# asynchronous task

最近我正在学习任务,并且我确实感动异步等待,我试着写一个简单的演示,请帮助检查我的编码是否有任何问题?为什么" x = ???"和" GetDataFromDbAsync结束"不能在控制台上打印?如果你能帮助我,我会很乐意。非常感谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;

namespace ConsoleApplication8
{
    class Program
    {
        static void Main(string[] args)
        {

            Test test = new Test();
            Console.WriteLine("main thread starts...");
            System.Threading.Thread.Sleep(1000);
            test.GetDataFromDb();
            Console.WriteLine("Mainthread end");
            Console.ReadKey();

        }
    }

    class Test
    {
        public void GetDataFromDb()
        {
            Console.WriteLine("GetDataFromDb starts");
            Task.Run(() => GetDataFromDbAsync());
            Console.WriteLine("GetDataFromDb ends");
        }

        public async Task<bool> GetDataFromDbAsync()
        {
            try
            {
                Console.WriteLine("GetDataFromDbAsync starts");
                var x = await ReadingDbAsync();
                Console.WriteLine("x=" + x);
                Console.WriteLine("GetDataFromDbAsync ends");
                return true;
            }
            catch(AggregateException ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

        public Task<int> ReadingDbAsync()
        {
            Console.WriteLine("ReadingDbAsync starts");
            System.Threading.Thread.Sleep(3000);
            var task= new Task<int>(() => 100);
            Console.WriteLine("ReadingDbAsync ends");
            return task;
        }
    }
}

以下是输出, demo output here

输出如下:

main thread starts...
GetDataFromDb starts
GetDataFromDb end
Mainthread end
GetDataFromDbAsync starts
ReadingDbAsync starts
ReadingDbAsync ends
**BUT WHY NOT SHOW THE FOLLOWING
x=100
GetDataFromDbAsync ends**

2 个答案:

答案 0 :(得分:1)

您不是awaitGetDataFromDb Console.ReadKey创建的任务。因此,在await GetDataFromDbAsync之后状态机恢复之前,执行将会Task。我怀疑如果你点击一个键,你会在应用程序退出之前看到你丢失的两个控制台消息。

您需要返回GetDataFromDb test.GetDataFromDb().Wait(); 并确保其已完成:

<a href="{{ route('route.name') }}">go first</a>

另请参阅this related question

答案 1 :(得分:1)

您的问题是您正在使用任务构造函数:

var task= new Task<int>(() => 100);

如果您想要一个代表同步值的任务,请使用Task.FromResult

var task = Task.FromResult(100);

正如我在博客中描述的那样,you should never, ever use task constructors