Pulled Apart - Part III: Get on the bus!
[](/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.
[](/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.