0

Here is my understanding of delegate: Delegate allows a method to accept a delegate as a parameter, and call the delegate at some later time. This is known as an asynchronous callback, and is a common method of notifying a caller when a long process has completed. When a delegate is used in this fashion, the code using the delegate does not need any knowledge of the implementation of the method being used.

Here is my code, however, it runs synchronously instead of asynchronously.

using System;

class Program
{
    delegate void MyDelegate(int result);

    static void Main()
    {
        Console.WriteLine("Starting long operation...");
        DoLongOperation(new MyDelegate(LongOperationCallback));
        Console.WriteLine("Continuing execution while long operation runs...");
        Console.ReadLine();
    }

    static void DoLongOperation(MyDelegate callback)
    {
        // Simulate a long operation that takes 5 seconds to complete
        System.Threading.Thread.Sleep(5000);
        callback(42); // Call the callback when the operation is complete
    }

    static void LongOperationCallback(int result)
    {
        Console.WriteLine($"Long operation completed with result: {result}");
    }
}

[![enter image description here][1]][1]

I thought the line 2 and line 3 should switch. [1]: https://i.stack.imgur.com/f3WcH.png

Flydog57
  • 6,851
  • 2
  • 17
  • 18
Lancer
  • 67
  • 6
  • This site provides a preview of questions and answers. Please look at the preview with your eyes and don't submit if it's a mess. Making it hard for us to read, and thus hard to understand, your question is a great way to not get the help you want. – jmcilhinney Apr 25 '23 at 04:45
  • What is your problem? A _Delegate_ is like a type-safe function pointer. You declare a delegate of a particular signature (`MyDelegate`), then you instantiate one of those delegates and pass it to a function expecting one (`DoLongOperation`). That function spins its wheels for 5 secs and invokes your delegate. Everything you are doing is being done synchronously on a single thread. Using a delegate doesn't add asynchony to your execution. The call to `DoLongOperation` including the invocation of your delegate will complete before your final `WriteLine` will start – Flydog57 Apr 25 '23 at 04:55

1 Answers1

0

To use an async callback you must use async code, so start by declaring Main as async. (If you can't make it async, see this question).

class Program
{
    static async Task Main()
    {
        Console.WriteLine("Starting long operation...");
        var task = DoLongOperation(LongOperationCallback);
        Console.WriteLine("Continuing execution while long operation runs...");
        Console.ReadLine();
        await task;
    }

    static async Task DoLongOperation(Action<int> callback)
    {
        // Simulate a long operation that takes 5 seconds to complete
        await Task.Delay(5000);
        callback(42); // Call the callback when the operation is complete
    }

    static void LongOperationCallback(int result)
    {
        Console.WriteLine($"Long operation completed with result: {result}");
    }
}

Because the task is not awaited until after the Readline(), it will run asynchronously.

See also Task asynchronous programming model.

John Wu
  • 50,556
  • 8
  • 44
  • 80
  • That's not much to do with the regular definition of "asynchronous callback" (which would be something like the old `ContinueWith` or the old APM model) that's just a delegate passed to an `async` function, and a rather unusual way to use it. Normally the caller would just do `await` then call whatever it wants. – Charlieface Apr 25 '23 at 09:33
  • The point of my answer was to convert the OP's original example into something that contains a callback that is asynchronous, using modern techniques. I would not recommend going back to the older model. This pattern is actually very useful when the callback is only called conditionally (e.g. the caller passes in an error handler) or the callback is called repeatedly (e.g. the caller passes in a progress update event handler). – John Wu Apr 25 '23 at 20:27