Andrey Bushman
Andrey Bushman

Reputation: 12476

How to wait a finish of the task and its continuation?

I learn to work with the threads on the base of a book.

I want to wait while my task and its continuation are working. But I see the "Press any key for exit..." message before "BLEEEEEEEEEEEEEEEP" (look the comments of my code, please). Why does it happen and how can I fix it?

I know that I can use two tasks and to use Task.Wait() for each of them, but what if I need to do the same for the continuation object?

enter image description here

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Bushman.Sandbox.Threads {
    class Program {
        static void Main(string[] args) {
            Console.Title = "Threads";

            try {
                // The main work
                Action act1 = () => {
                    for (int i = 0; i < 10; i++) {

                        int id = Thread.CurrentThread
                        .ManagedThreadId;

                        Console.WriteLine(
                            "bleep. Thread Id: {0}",
                            id.ToString());
                    }
                };

                // This operation is to be done when the main 
                // work will be finished.
                Action act2 = () => {

                    int id = Thread.CurrentThread
                        .ManagedThreadId;

                    Console.WriteLine(
                        "bleep. Thread Id: {0}",
                        id.ToString());

                    Console.WriteLine(
                        "BLEEEEEEEEEEEEEEEP. Thread Id: {0}",
                            id.ToString());
                };

                Task task = new Task(act1);
                var awaiter = task.GetAwaiter();
                awaiter.OnCompleted(act2);

                Console.WriteLine("Work started...");
                task.Start();

                // TODO: wait while both actions will be done

                task.Wait(); // it doesn't work as I expected

                // it doesn't work as I expected too...
                awaiter.GetResult();
            }
            catch (Exception ex) {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);
                Console.ResetColor();
            }

            Console.WriteLine("Press any key for exit...");
            Console.ReadKey();
        }
    }
}

Upvotes: 0

Views: 1578

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

The OnCompleted event is triggered on a different thread that you are not waiting for. You could use the following construct:

Task task = new Task(act1);
var awaiter = task.ContinueWith(x => act2()).GetAwaiter();
task.Start();

Console.WriteLine("Work started...");

awaiter.GetResult();

In this case act1 will be executed using the first task and when this task is completed it will continue with act2. The awaiter in this case will wait for both to complete.

Upvotes: 5

Related Questions