Jacob
Jacob

Reputation: 91

The text after await cannot be printed out in async void method

Recently I'm learning Task and certailly I touched async await, and i tried to write a simple demo, please kindly help check whether there are any problems in my coding? And why the "x=???" and "GetDataFromDbAsync ends" not be printed on console? I would much appreicate if you could help me out. Thanks a lot.

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

The following is the output, demo output here

Output as following:

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**

Upvotes: 0

Views: 511

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 457137

Your problem is that you're using the task constructor:

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

If you want a task that represents a synchronous value, use Task.FromResult:

var task = Task.FromResult(100);

As I describe on my blog, you should never, ever use task constructors.

Upvotes: 1

Charles Mager
Charles Mager

Reputation: 26223

You're not awaiting the task you're creating in GetDataFromDb. As a result, the execution will hit Console.ReadKey before state machine resumes after the await in GetDataFromDbAsync. I suspect if you hit a key, you'll see your two missing console messages before the application exits.

You need to return a Task GetDataFromDb and ensure it has completed:

test.GetDataFromDb().Wait();

Also, see this related question

Upvotes: 1

Related Questions