Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async function finishes too early

Let's look at the following code:

class C
{
    static void Main(string[] args)
    {
        Task t = new Task(DoSthAsync);
        t.Start();
        t.Wait();
        Console.WriteLine("Finished?");
    }

    static async void DoSthAsync()
    {
        using (StreamReader reader = new StreamReader("file.txt"))
        {
            int i = 1;
            while (!reader.EndOfStream)
            {
                Console.WriteLine("{0}: {1}", i++, await reader.ReadLineAsync());
            }
        }
    }
}

I get really confused. Shouldn't this code work synchronously since I am directly awaiting async method? From a 1000 line file I get only 76 lines printed. Why is that?

like image 819
bottaio Avatar asked Jun 03 '26 18:06

bottaio


1 Answers

You are using async void which you should never do unless you are working with events. First you need to make your function return a Task instead of void, you then must use Task.Run instead of new Task so that it can handle the async function for you.

static void Main(string[] args)
{
    Task t = Task.Run(() => DoSthAsync()); // "Task.Run((Func<Task>)DoSthAsync)" would also work.
    t.Wait();
    Console.WriteLine("Finished?");
}

static async Task DoSthAsync()
{
    using (StreamReader reader = new StreamReader("file.txt"))
    {
        int i = 1;
        while (!reader.EndOfStream)
        {
            Console.WriteLine("{0}: {1}", i++, await reader.ReadLineAsync());
        }
    }
}

Your old way had no way of knowing that the inner task was complete, t.Wait() was only waiting till the first non synchronous completion of reader.ReadLineAsync(), by returning a Task your outer function now has a way to detect when the inner function is fully complete and not just waiting for its first continuation.

like image 125
Scott Chamberlain Avatar answered Jun 06 '26 07:06

Scott Chamberlain



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!