In C#, the Action delegate type signifies a method that can be called but does not yield a return value, as its return type is void. It is capable of accepting zero or more input parameters.

Action resides within the System namespace and is available in various overloads to accommodate different quantities of parameters. It is frequently utilized for passing methods as arguments, establishing callbacks, or creating event handlers.

Action Syntax

Key Features

Comparison with Func

For example

The appropriate context for utilizing Action

  1. Action is a delegate type used for methods that don't return values.
  2. It is useful for passing methods as parameters or defining callbacks.
  3. You can use Action for methods with zero to 16 input parameters.

Examples of different types of Action delegates

Execution of all previously mentioned actions within the application

Step 1. I have developed a WPF user interface, as illustrated below. You may select any application type that aligns with your specific requirements.

WPF

MainWindow.Xaml code

<Window 
    x:Class="ActionDelegateExample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ActionDelegateExample"
    mc:Ignorable="d"
    Title="MainWindow" 
    Height="450" 
    Width="800">
    
    <Grid>
        <StackPanel Orientation="Vertical">
            <Button 
                x:Name="BtnNoParameter" 
                Content="Action with no Parameter" 
                Click="BtnNoParameter_Click" 
                Height="40" 
                Margin="20"/>
            
            <Button 
                x:Name="BtnWithSingleParameter" 
                Content="Action with single Parameter" 
                Click="BtnWithSingleParameter_Click" 
                Height="40" 
                Margin="20"/>
            
            <Button 
                x:Name="BtnMultipleParameter" 
                Content="Action with multiple Parameter" 
                Click="BtnMultipleParameter_Click" 
                Height="40" 
                Margin="20"/>
            
            <Button 
                x:Name="BtnCallbackParameter" 
                Content="Action with call back" 
                Click="BtnCallbackParameter_Click" 
                Height="40" 
                Margin="20"/>
            
            <Button 
                x:Name="BtnCallEvenHandlingParameter" 
                Content="Action with CallEvenHandling" 
                Click="BtnCallEvenHandlingParameter_Click" 
                Height="40" 
                Margin="20"/>
        </StackPanel>
    </Grid>
</Window>

MainWindow.Xaml.cs code

using System.Windows;

namespace ActionDelegateExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            EventHandlerManager.OnEventRaised += EventHandlerManager_OnEventRaised;
        }
        private void EventHandlerManager_OnEventRaised()
        {
            MessageBox.Show("Event handled by Subscriber");
        }
        private void BtnNoParameter_Click(object sender, RoutedEventArgs e)
        {
            ActionMethods.NoParameterActionVariable();
        }
        private void BtnWithSingleParameter_Click(object sender, RoutedEventArgs e)
        {
            // Create a RequestMessage
            RequestMessageWithParameter message = new RequestMessageWithParameter 
            { 
                Content = "This is a single parameter request." 
            };
            ActionMethods.ActionWithOneParameter(message);
        }
        private void BtnMultipleParameter_Click(object sender, RoutedEventArgs e)
        {
            // Create a RequestMessage
            RequestMessageWithParameter message = new RequestMessageWithParameter 
            { 
                Content = "This is a multiple parameter request." 
            };

            // Invoke the Action with RequestMessage and an integer
            ActionMethods.ActionWithTwoParameters(message, 42);
        }
        private void BtnCallEvenHandlingParameter_Click(object sender, RoutedEventArgs e)
        {
            EventHandlerManager.RaiseOnEventRaised();
        }
        private void BtnCallbackParameter_Click(object sender, RoutedEventArgs e)
        {
            MessageHandler handler = new MessageHandler();

            // Define the callback action that will handle the RequestMessage after processing
            Action<RequestMessageWithParameter> callback = (request) =>
            {
                MessageBox.Show($"Callback executed. Message content: {request.Content}");
            };
            // Call the method with a message and the callback action
            handler.ProcessRequest("Hello, this is a sample request!", callback);
        }
    }
}

Step 2. Establish a class titled "ActionMethods.cs" as illustrated below. It has been used to define action delegates

using System.Windows;

namespace ActionDelegateExample
{
    public class ActionMethods
    {
        public static Action NoParameterActionVariable = () => NoParameterAction();
        private static void NoParameterAction()
        {
            MessageBox.Show("Action without parameters executed.");
        }
        // Action that accepts one parameter of type RequestMessage
        public static Action<RequestMessageWithParameter> ActionWithOneParameter = (request) =>
        {
            MessageBox.Show(request.Content);
        };
        // Action that accepts two parameters: RequestMessage and an integer
        public static Action<RequestMessageWithParameter, int> ActionWithTwoParameters = (request, count) =>
        {
            MessageBox.Show($"Action with two parameters executed. Message: {request.Content}, Count: {count}");
        };
    }
}

Step 3. Create a class named “MessageHandler.cs” as shown below. It will be used to manage an event of action type.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ActionDelegateExample
{
    public class MessageHandler
    {
        // Method that accepts an Action<RequestMessage> callback
        public void ProcessRequest(string messageContent, Action<RequestMessageWithParameter> callback)
        {
            // Create the RequestMessage
            RequestMessageWithParameter requestMessage = new RequestMessageWithParameter { Content = messageContent };

            // Simulate some processing
            Console.WriteLine("Processing the message...");
            System.Threading.Thread.Sleep(10000);

            // After processing, invoke the callback with the request message
            callback?.Invoke(requestMessage);
        }
    }
}

Step 4. Create a class by the name of ‘EventHandlerManager.cs” to handle the event.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ActionDelegateExample
{
    public class EventHandlerManager
    {
        public static event Action OnEventRaised;
        // Method to raise the event
        public static void RaiseOnEventRaised()
        {
            Action onEventRaised = OnEventRaised;
            if (onEventRaised != null)
            {
                onEventRaised();
            }
        }
    }
}

A detailed description of the aforementioned code

Step 6. The results obtained from testing are.

Repository Path: https://github.com/OmatrixTech/ActionDelegateExample