Angel \”Java\” Lopez on Blog

January 2, 2010

GoRoutines and Channels in C#

Filed under: .NET, C Sharp — ajlopez @ 10:56 am

In my previous posts:

Channel and GoRoutines in AjSharp (Part 1)
Channel and GoRoutines in AjSharp (Part 2)

I described the implementation of goroutines and channels in my AjSharp interpreter. At the end of last year, I wrote a quick spike, implementing the same concepts, but this time directly in C#. You can download the code from

http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjConcurr

First, I port the Channel class:

public class Channel
{
    private AutoResetEvent sethandle = new AutoResetEvent(false);
    private AutoResetEvent gethandle = new AutoResetEvent(false);
    private object value;

    public void Send(object value)
    {
        this.gethandle.WaitOne();
        this.value = value;
        this.sethandle.Set();
    }

    public object Receive()
    {
        this.gethandle.Set();
        this.sethandle.WaitOne();
        object result = this.value;
        return result;
    }
}

The code has an static class GoRoutines, with methods like:

public static void Go(Action action)
{
    Thread thread = new Thread(new ParameterizedThreadStart(GoRoutines.RunAction));
    thread.IsBackground = true;
    thread.Start(action);
    //ThreadPool.QueueUserWorkItem(new WaitCallback(RunAction), action);
}

public static void Go(ITask task)
{
    Thread thread = new Thread(new ParameterizedThreadStart(GoRoutines.RunTask));
    thread.IsBackground = true;
    thread.Start(task);
    //ThreadPool.QueueUserWorkItem(new WaitCallback(RunTask), task);
}

You can launch an Action (a delegate System.Action<>, already defined in .NET framwork), in a new thread (I tried to put it in the queue tasks of ThreadPool, but, I don’t know why, the performance was too low; see my attemp in the comments in GoRoutines code).

When an action receives parameters, I encapsulated both in a Task<>, like this:

public class Task<T1, T2> : ITask
{
    private Action<T1, T2> action;
    private T1 parameter1;
    private T2 parameter2;

    public Task(Action<T1, T2> action, T1 parameter1, T2 parameter2)
    {
        this.action = action;
        this.parameter1 = parameter1;
        this.parameter2 = parameter2;
    }

    public void Run()
    {
        this.action(this.parameter1, this.parameter2);
    }
}

(there are Task classes for one, two and three parameters).

You can invoke GoRoutines.Go directly specifying an action and its parameters:

public static void Go<T1, T2>(Action<T1, T2> action, T1 parameter1, T2 parameter2)
{
    Go(new Task<T1, T2>(action, parameter1, parameter2));
}

You can write the invoke using lambda expressions:

[TestMethod]
public void RunGoRoutineWithTwoParameters()
{
    int i = 0;
    AutoResetEvent handle = new AutoResetEvent(false);
    GoRoutines.Go((x, y) => { i = x + y; handle.Set(); }, 2, 3);
    handle.WaitOne();
    Assert.AreEqual(5, i);
}

With all this implemented, I wrote a console application AjConcurr.Primes, reimplementing the primes examples of my previous post:

Channel numbers = new Channel();
GoRoutines.Go(() => { for (int k = 2; ; k++) numbers.Send(k);  });
Channel channel = numbers;
int prime = 0;
while (prime < 1000)
{
    prime = (int)channel.Receive();
    Console.WriteLine(prime);
    Channel newchannel = new Channel();
    GoRoutines.Go((input, output, p) =>
    {
       while (true)
       {
           int number = (int)input.Receive();
           if ((number % p) != 0)
               output.Send(number);
       }
    }, channel, newchannel, prime);
    channel = newchannel;
}

I love to see this code formatted in pastie:

http://pastie.org/761916

Next steps:

- Improve Channel to support multiple simultaneous producers and consumers.

- Add Futures support

- Add reactive programming features.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

2 Comments »

  1. [...] GoRoutines and Channels in C# [...]

    Pingback by Genetic Algorithms using GoRoutines and Channels in C# « Angel “Java” Lopez on Blog — February 7, 2010 @ 10:39 am

  2. [...] in AjSharp (Part 1) Channels and GoRoutines in AjSharp (Part 2) GoRoutines y Canales en C# GoRoutines and Channels in C# AjSharp: Implementing Futures AjSharp: Implementando Futures Queue Channels in AjSharp Queue [...]

    Pingback by Agentes en AjSharp (Parte 1) - Angel "Java" Lopez — February 13, 2010 @ 10:51 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 57 other followers

%d bloggers like this: