bottaio
bottaio

Reputation: 5073

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?

Upvotes: 2

Views: 1326

Answers (2)

Scott Chamberlain
Scott Chamberlain

Reputation: 127543

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.

Upvotes: 13

Ritesh
Ritesh

Reputation: 1847

You need to hold on the main thread as when new thread gets spawned for the task, it works but your main thread exists before even task gets complete.

You have to make sure that main thread does exit before your worker threads finishes up.

May you can use mutex

Upvotes: -2

Related Questions