Pulled Apart - Part III: Get on the bus!

[![onebit_26](/files/onebit_26_thumb_1.webp)](/files/onebit_26_1.webp)
Note: This is part of a series. You can find the rest of the parts in the [series index](/content/pulled-apart-series-index).

One of the aspects of [Pull](https://pull.codeplex.com) is that it had to be multi-threaded—because things like downloading a massive podcast shouldn’t lock up the UI. Threading has become pretty easy in .NET 4 thanks to things like PLINQ or Parallel Extensions. However, cross-thread communication hasn’t gotten easier in .NET 4.

My idea to solve this was to create an *internal bus*—which is just an implementation of the pub/sub pattern. A bunch of subscribers register with the bus for a specific message type, and when a message is given to the bus, it passes it to the correct subscribers.

[![image](/files/image_thumb_61.webp)](/files/image_36.webp)

First, I created a simple singleton instance of my bus class:

```csharp
internal class Bus
{
    private static Bus bus = new Bus();

    private Bus()
    {
        publisher = new Publisher();
    }

    public static Bus GetBus()
    {
        return bus;
    }

This ensures that all threads get the same instance. Inside my bus class, I implemented the new .NET 4 IObserver/IObservable interfaces, which gave me all the pub/sub magic. This is all internal to the bus class so that usage in my application is straightforward—for example, the methods for registering a subscriber hide the pub/sub concept completely:

public void Register<T>(DataAction actions, Action<T> method, Control control = null)
{
    publisher.Subscribe(new Subscriber<T>(actions, method, control));
}

public void Register(DataAction actions, Action method, Control control = null)
{
    Action<object> fakeMethod = value => { method(); };
    this.Register(actions, fakeMethod, control);
}

One of the options when registering a subscriber is passing in a control, which I use for handling objects owned by other threads—making it very easy to update the UI.

Broadcasting to all subscribers who have registered for a message type is handled by a very simple method:

public void Broadcast<T>(DataAction action, T data)
{
    publisher.Update(action, data);
}

public void Broadcast(DataAction action)
{
    this.Broadcast<object>(action, null);
}

To identify the type of message, I used an enum—which I don’t feel great about. The advantage of using enums is that there’s no magic strings (the compiler can’t identify them, e.g., if I mistype a message) and I can use flags to broadcast multiple messages at once. However, the downside is that adding a new message requires editing the enum list, which isn’t ideal.

Final Thoughts

Overall, I’m exceptionally happy with the bus—it solved so many problems I’d had with multi-threaded applications and should be a standard in application design in the future.