This is a series of articles about Multi-threading.
- Multi-Threading (1), Concept: What, Why
- Multi-Threading (2), Implementation Overview
- Multi-Threading (3), async, await in C#
- Multi-Threading (4), delegate based Asynchronous Programming Model --- this article
- Multi-Threading (5), Summary
Introduction
The article, Multi-Threading (2), Implementation Overview, gave three different implementation models for asynchronous programming. This article will discuss APM with examples.
An asynchronous Programming Model (APM) is a native or raw asynchronous programming model using a delegate to create a thread. such that you define a delegate with the same signature as the method you want to call, the common language runtime automatically defines BeginInvoke and EndInvoke methods for this delegate, with the appropriate signatures. Therefore we could say APM is a delegate-based Asynchronous Programming model, as we used as the article name.
Content of the article
- Introduction
- EndInvoke: Waiting for an Asynchronous Call with EndInvoke
- WaitHandle: Waiting for an Asynchronous Call with WaitHandle
- Poll: Polling for Asynchronous Call Completion
- Call back: Executing a Callback Method When an Asynchronous Call Completes
- Summary
EndInvoke: Waiting for an Asynchronous Call with EndInvoke
Pattern
- Call
to start a new async thread; - Call
to end the async calling thread.
EndInvoke might block the calling thread because it does not return until the asynchronous call completes. This is a good technique to use with file or network operations.
Create a delegate: AsyncMethodCaller.
// The delegate must have the same signature as the method
// it will call asynchronously.
public delegate string AsyncMethodCaller(int callDuration, out int threadId);
Create a Test Method, AsyncDemo, and make a test program.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
// https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously
// Modified, https://www.c-sharpcorner.com/article/multi-threading-4-delegate-based-asynchorous-programming-model/
namespace Async_Await
{
class Multi_Await6
{
// if not shown in Start up object, use this non async main
public static void Main(string[] args)
{
// The asynchronous method puts the thread id here.
int threadId;
// Create an instance of the test class.
AsyncDemo ad = new AsyncDemo();
// Create the delegate.
AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
ConsoleWriteLine($"Line {27}");
// Initiate the asynchronous call.
IAsyncResult result = caller.BeginInvoke(3000,
out threadId, null, null);
Thread.Sleep(0);
ConsoleWriteLine($"Line {35}");
// Call EndInvoke to wait for the asynchronous call to complete,
// and to retrieve the results.
string returnValue = caller.EndInvoke(out threadId, result);
ConsoleWriteLine($"Line {41}");
Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
threadId, returnValue);
Console.ReadLine();
}
public class AsyncDemo
{
// The method to be executed asynchronously.
public string TestMethod(int callDuration, out int threadId)
{
Console.WriteLine("Test method begins.");
ConsoleWriteLine($"Line {56}");
Thread.Sleep(callDuration);
threadId = Thread.CurrentThread.ManagedThreadId;
return String.Format("My call time was {0}.", callDuration.ToString());
}
}
// The delegate must have the same signature as the method
// it will call asynchronously.
public delegate string AsyncMethodCaller(int callDuration, out int threadId);
// Convenient helper to print colorful threadId on console
static void ConsoleWriteLine(string str)
{
int threadId = Thread.CurrentThread.ManagedThreadId;
//Console.ForegroundColor = threadId == 1 ? ConsoleColor.White : ConsoleColor.Cyan;
switch (threadId)
{
case 1:
Console.ForegroundColor = ConsoleColor.White;
break;
case 3:
Console.ForegroundColor = ConsoleColor.Green;
break;
}
Console.WriteLine(
$"{str}{new string(' ', 26 - str.Length)} Thread {threadId}");
}
}
}
The BeginIvoke method creates a new thread at Line 30; the thread ends at Line 39 by the EndIvoke method.

Run the program and the output.
The method AsyncDemo is run asynchronously, with thread number 3 shown in green at Line 56 in the output.








to make the poll in the same step as an async method, Run the code we have output.




Join the conversation! Your thoughts help the community grow.