I've recently been experimenting with C#'s delegates, and here is an example of how they can be used for multithreading. I've used a ray tracer as a good example of something that can be multithreaded easily. This ray tracer has been grabbed from LukeH's awesome LINQ example here: LukeH's WebLog A Ray Tracer in C# 3.0. I've modified it a bit for my purposes just a little. What i'm trying to accomplish here is getting 4 delegates to render different parts of a scene in simultaneous threads, and stitch them together for one image, and save it to disk. Firstly, you've got to declare a delegate type. It's a little like creating a new enum, in that you're creating a new variable type. This code goes in the class declaration, outside of any functions. In my case, i'm declaring that my delegate has 2 parameters:
delegate void RenderSection(int top, int bottom);
Now i've got my delegate, i want to create my function that fits with the delegate's signature of taking 2 integers:
/// <summary>
/// This is the delegate that renders a part of the image, a delegate for RenderSection
/// </summary>
public void RenderASection(int top, int bottom)
{
  // Raytrace just this section of the scene
  Bitmap SectionBitmap = new Bitmap(width, height);
  RayTracer rayTracer = new RayTracer(width, height,
    (int x, int y, System.Drawing.Color color) =>
      {
        SectionBitmap.SetPixel(x, y, color);
      }
    );
  rayTracer.Render(rayTracer.DefaultScene, top, bottom);

  // Copy my part of the scene into the overall scene
  lock (bitmap)
  {
    Graphics g = Graphics.FromImage(bitmap);
    g.DrawImage(
      SectionBitmap,
      new Rectangle(0, top, width, bottom),
      new Rectangle(0, top, width, bottom),
      GraphicsUnit.Pixel);
  }
}
Okay, now i've got my delegate type and my actual delegate, i want to use them, as i do in my Run function below. Notice that for the 3rd one, i'm using an anonymous delegate for the "Hey: I've finished" callback, for no real reason. The 'CallbackMethod' function is another delegate, matching the signature for the AsyncCallback delegate type.
public void Run()
{
  width = 800;
  height = 800;
  bitmap = new Bitmap(width, height);

  RenderSection myDelegate = RenderASection;

  // Run it with different parameters
  IAsyncResult ar1 = myDelegate.BeginInvoke(0, 200, CallbackMethod, null);
  IAsyncResult ar2 = myDelegate.BeginInvoke(200, 400, CallbackMethod, null);
  IAsyncResult ar3 = myDelegate.BeginInvoke(400, 600,
    delegate(IAsyncResult ar)
      { Console.WriteLine("Section finished (anonymous delegate)"); },
    null);
  IAsyncResult ar4 = myDelegate.BeginInvoke(600, height, CallbackMethod, null);

  // Wait for them to finish
  myDelegate.EndInvoke(ar1);
  myDelegate.EndInvoke(ar2);
  myDelegate.EndInvoke(ar3);
  myDelegate.EndInvoke(ar4);
  
  // Save the output bitmap
  bitmap.Save("RayTrace.png");
}

/// <summary>
/// This is a function we can use as a delegate for AsyncCallback 
/// </summary>
void CallbackMethod(IAsyncResult ar)
{
  Console.WriteLine("Section finished");
}
Here is the entire solution (VS2008): multithreadeddelegatesraytracedemo Cheers, and thanks for reading.

Thanks for reading! And if you want to get in touch, I'd love to hear from you: chris.hulbert at gmail.

Chris Hulbert

(Comp Sci, Hons - UTS)

iOS Developer in Sydney.

I have worked at places such as Google, Cochlear, News Corp, Fox Sports, NineMSN, FetchTV, Woolworths, and Westpac, among others. If you're looking for a good iOS developer, drop me a line!

Get in touch:
[email protected]
github.com/chrishulbert
linkedin
my resume



 Subscribe via RSS