0

How would I make the main thread wait until DisplayAdd has displayed the output? If I add a Console.Read() at the end, everything works but is there another way to tell the main thread to wait until Calculate() has finished?

namespace TestDelegate
{
    public class Add
    {
        public delegate void SendResult(int i);
        public SendResult WhereToSend;

        public async void Calculate (int number)
        {
            Console.WriteLine("Entered");
            int result = number + number;
            await Task.Delay(4000);
            WhereToSend (result);
           // Console.Read();

        }

    }
}


namespace TestStuff
{
    class Program
    {

        static void Main(string[] args)
        {


            Add obj = new Add();
            Console.WriteLine("Started Calculating");
            obj.Calculate(10);
            obj.WhereToSend = DisplayAdd;

        }

        static void DisplayAdd(int value)
        {

            Console.WriteLine(value);
        }

    }
}
HJ1990
  • 385
  • 1
  • 4
  • 19
  • As noted in the marked duplicate, the reason you have this problem is that your `async` method returns `void`. You need to return a `Task`, then you can `await` it. On a related note: your `async` method implementation is broken, as it relies on the timing between the caller and the execution of the method. The right way to implement it is to make sure that the caller has set `WhereToSend` before calling the method (throw an exception if it's not), or even better, make that a _parameter_ to the method instead of a field. At the very least, use `?.` to invoke the delegate to ward against `null` – Peter Duniho Oct 10 '19 at 18:10

1 Answers1

3

You can define the delegate as Task return type (awaitable type). With this the method will finish before main thread terminates.

namespace TestDelegate
{
    public delegate Task SendResult(int i);
    public class Add
    {   
        public SendResult WhereToSend;

        public async Task Calculate (int number)
        {
            Console.WriteLine("Entered");
            int result = number + number;

            await WhereToSend (result);
        }
    }
}


namespace TestStuff
{
    class Program
    {

        static void Main(string[] args)
        {   
            Add obj = new Add();
            obj.WhereToSend = DisplayAdd;
            Console.WriteLine("Started Calculating");
            obj.Calculate(10).Wait();
        }

        static async Task DisplayAdd(int value)
        {
            // Some awaitable operation like below as per your business logic
            await Task.Delay(1);
            Console.WriteLine(value);
        }

    }
}

In above program, I've changed the definition of Calculate method to async Task so that it can be marked for Waitable. The async void method are primarily used for UI events hanlder or fire and forget method.

Please check this dotnetfiddle which demonstrates the scenario.

user1672994
  • 10,509
  • 1
  • 19
  • 32