Click here to Skip to main content
6,629,885 members and growing! (19,844 online)
Email Password   helpLost your password?
Languages » C# » Delegates and Events     Intermediate License: The Code Project Open License (CPOL)

Action Extensions

By leppie

Parallelization of multicast delegates
C# (C# 3.0), Windows, Dev
Posted:1 Jul 2008
Views:7,549
Bookmarked:21 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
15 votes for this article.
Popularity: 5.39 Rating: 4.58 out of 5
1 vote, 6.7%
1
1 vote, 6.7%
2
1 vote, 6.7%
3
1 vote, 6.7%
4
11 votes, 73.3%
5

Introduction

Ennis Ray Lynch, Jr. gave me an idea the other day in the Lounge. The basic idea was running multicast delegates in parallel.

Background

The code to run delegates in parallel is rather trivial.

static void Run(Action[] aa)
{
  List<IAsyncResult> waits = new List<IAsyncResult>();

  foreach (Action a in aa)
  {
    waits.Add(a.BeginInvoke(null, null));
  }

  foreach (IAsyncResult ar in waits)
  {
    ar.AsyncWaitHandle.WaitOne();
  }
}

To run a multicast delegate in parallel follows the same pattern.

static void Run(Action t)
{
  List<IAsyncResult> waits = new List<IAsyncResult>();

  foreach (Action a in t.GetInvocationList())
  {
    waits.Add(a.BeginInvoke(null, null));
  }

  foreach (IAsyncResult ar in waits)
  {
    ar.AsyncWaitHandle.WaitOne();
  }
}

Using the Code

Following the above pattern, we simply create stubs for the generic Action delegate (only 1 shown for clarity). If needed, you can replace with your own delegate type. There is one important aspect to keep in mind; the delegate MUST return void. Why, you may ask? The answer is simple. There is no easy way to consume multiple return values in C#.

static class ActionExtensions
{
  class WaitList : IDisposable
  {
    readonly List<IAsyncResult> waits = new List<IAsyncResult>();

    public void Add(IAsyncResult ar)
    {
      waits.Add(ar);
    }

    public void Dispose()
    {
      foreach (var ar in waits)
      {
        ar.AsyncWaitHandle.WaitOne();
      }
    }
  }

  public static Action MakeParallel(this Action t)
  {
    return () =>
    {
      using (var w = new WaitList())
      {
        foreach (Action a in t.GetInvocationList())
        {
          w.Add(a.BeginInvoke(null, null));
        }
      }
    };
  }
}

The usage is also trivial. Simply call the MakeParallel extension method.

class Program
{
  static void Main(string[] args)
  {
    Action<int> f = null;

    for (int i = 0; i < 8; i++)
    {
      f += Thread.Sleep;
    }

    Stopwatch ws = Stopwatch.StartNew();

    f(250);

    Console.WriteLine("ser: {0:f3}", ws.Elapsed.TotalMilliseconds);

    f = f.MakeParallel();

    ws = Stopwatch.StartNew();

    f(250);

    Console.WriteLine("par: {0:f3}", ws.Elapsed.TotalMilliseconds);

    Console.ReadLine();
  }
}

The output should show the parallel version running at half (or quarter) the time of the serial version.

Points of Interest

From what I can determine, BeginInvoke utilizes the number of logical CPUs. I have however not been able to test this.

History

  • 2nd July, 2008 - Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

leppie


Member

Occupation: Software Developer
Location: South Africa South Africa

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 7 of 7 (Total in Forum: 7) (Refresh)FirstPrevNext
GeneralNice, but you should call EndInvoke() PinmemberJelle Hissink10:48 6 Jul '08  
GeneralRe: Nice, but you should call EndInvoke() Pinmemberleppie11:20 6 Jul '08  
GeneralSweet PinmemberNick Butler23:28 3 Jul '08  
GeneralRe: Sweet Pinmemberleppie8:21 4 Jul '08  
GeneralNice work Pinmemberkin3tik6:42 2 Jul '08  
GeneralNice PinmvpPete O'Hanlon23:33 1 Jul '08  
GeneralRe: Nice Pinmemberleppie23:48 1 Jul '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 1 Jul 2008
Editor: Deeksha Shenoy
Copyright 2008 by leppie
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project