AJ's blog

July 26, 2010

Flurfunk

Filed under: Blogroll, SDX — ajdotnet @ 7:59 pm

Recently I have been blogging a little less than usual. One reason for that was that my company started its corporate blog, named „Flurfunk“ (German, „water-cooler conversation“?). And being an experienced blogger… they said… and I was arrested. Anyway, it’s in German, therefore…

flurfunk<content locale=”de; de-DE”>

… für die der deutschen Sprache mächtigen Leser: SDX hat den firmeneigenen Blog „Flurfunk” gestartet.

Die Themen sind ein bunter Mix aus kleineren technischen Artikeln (und Kollegen die das mit dem “klein” noch nicht verstanden haben :-P), netten Hinweisen aus dem Back-Office  ;-), aktuelles aus dem Büro, Veranstaltungshinweise – und nicht zuletzt Marketing.
OK, auch nicht ganz so ernst gemeintes ist dabei ;o). Schön bunt ist‘s auf jeden Fall!

Einfach mal reinschauen und guten Tag sagen 🙂

</content>

That’s all for now folks,
AJ.NET

July 24, 2010

Replacing Events by Callbacks

Filed under: .NET, .NET Framework, C#, Silverlight, Software Development — ajdotnet @ 1:57 pm

My last post laid out how the employment of events has changed recently. Most importantly the broadcasting scenario – which was the major pattern so far – is no longer the only relevant pattern. Rather the “event-based asynchronous pattern”, MSDN, has emerged. Reasons include the inherently asynchronous nature of Silverlight as well as parallel patterns.

Now for the practical implications of this new pattern. Let’s look at an example to get the idea, and a better understanding of the consequences in code…

Let’s assume a component that is instantiated, does some work (allegedly asynchronous, and notifying about the progress) and provides the result at the end via an event. This is akin to making a server call, showing a confirmation message box, or the way the BackgroundWorker component works.

Example 1: Using events

First, implementing the a component the classical way would look somewhat like this:

The result event needs a respective EventArgs class, the declaration and the trigger method:

public class WorkResultEventArgs : EventArgs
{
    public object ResultData { get; set; }
}

public class MyWorkingComponent1
{
    public event EventHandler<WorkResultEventArgs> WorkResult;
    
    protected virtual void OnWorkResult(object resultData)
    {
        if (WorkResult != null)
            WorkResult(this, new WorkResultEventArgs() { ResultData = resultData });
    } 
    …
}

A work progress event should go a little further and provide cancelation support:

public class WorkProgressEventArgs : CancelEventArgs
{
    public int Progress { get; set; }
    public object SomeData { get; set; }
}

public class MyWorkingComponent1

    public event EventHandler<WorkProgressEventArgs> WorkProgress;
    
    protected virtual bool OnWorkProgress(int progress, object someData)
    {
        if (WorkProgress == null)
            return true;
        
        var ea = new WorkProgressEventArgs() { Progress = progress, SomeData = someData, Cancel = false };
        WorkProgress(this, ea);
        return ea.Cancel ? false : true;
    }
    …
}

Now we only need the actual worker method:

public class MyWorkingComponent1

    …
     
    public void StartWork()
    {
        int sum = 0;
        for (int i = 0; i < 10; ++i)
        {
            sum += i;
            if (!OnWorkProgress(i, sum))
                return;
        }
        OnWorkResult(sum);
    }
}

Again, we may assume that there is some asynchronicity involved, e.g. the loop could contain a web request or something. But this example should do for the sake of the argument.

The usage (as by support form Visual Studio to create the event handlers) would look like this:

public void Test1()
{
    var worker = new MyWorkingComponent1();
    worker.WorkProgress += new EventHandler<WorkProgressEventArgs>(Worker_WorkProgress);
    worker.WorkResult += new EventHandler<WorkResultEventArgs>(Worker_WorkResult);
    
    worker.StartWork();
}

void Worker_WorkProgress(object sender, WorkProgressEventArgs e)
{
    Console.WriteLine(e.Progress + ":" + e.SomeData);
}

void Worker_WorkResult(object sender, WorkResultEventArgs e)
{
    Console.WriteLine("Result:" + e.ResultData);
}

Creating the component, registering the event handlers, running the task, throw the component away. The fact that events are multi cast capable is never used at all (and never will, as the component is rather short-lived).

I guess we can agree that this is all very boilerplate. And all in all, that’s quite some overhead, from the component perspective as well as from the client code.

Example 2: Using callbacks

Now let’s try the new approach. Rather than defining an event, I pass in two callbacks. The information that was carried in the EventArgs is moved to the parameter lists, thus no need for these classes. The Cancel property is replaced by the return value of the callback. And since the client code always follows the same idiom, I expect the callbacks as constructor parameters, eliminating a source of errors along the way — something that is not possible with event handlers:

public class MyWorkingComponent2

    public Action<MyWorkingComponent2, object> WorkResult {get;set;} 
    public Func<MyWorkingComponent2, int, object, bool> WorkProgress { get; set; } 
         
    public MyWorkingComponent2( 
        Action<MyWorkingComponent2, object> workResult, 
        Func<MyWorkingComponent2, int, object, bool> workProgress) 
    { 
        WorkResult = workResult; 
        WorkProgress= workProgress; 
    } 
    …
}

The worker method changes only slightly:

public class MyWorkingComponent2

    …
         
    public void StartWork() 
    { 
        int sum = 0; 
        for (int i = 0; i < 10; ++i) 
        { 
            sum += i; 
            if (!WorkProgress(this, i, sum)) 
                return
        } 
        WorkResult(this, sum); 
    } 
}

That’s it. No EventArgs classes, no events, no respective OnEventHappened methods. Granted, the callback declarations are a little more complex, and their parameters also lack intellisense providing information about the semantics of each parameter. But otherwise? Way shorter, way more concise, way less overhead. The actual worker method hasn’t changed at all, but all the event related overhead is gone, which amounted to only 40% LOC.

Now the client code, first only slightly adapted:

public void Test1()
{
    var worker = new MyWorkingComponent2(
        (sender, resultData) => Worker_WorkResult(sender, resultData),
        (sender, progress, someData) => Worker_WorkProgress(sender, progress, someData)
    );
    
    worker.StartWork();
}

bool Worker_WorkProgress(object sender, int progress, object someData)
{
    Console.WriteLine(progress + ":" + someData);
    return true;
}

void Worker_WorkResult(object sender, object resultData)
{
    Console.WriteLine("Result:" + resultData);
}

As you can see, it didn’t change that much. But passing in the lambdas via the constructor fits the use case far better than events, and it is even more robust, as I cannot forget to pass in a callback via the constructor, the way I can forget to register an event handler.

Speaking of lambdas, and since the implementation is that simple, we can even simplify the client code further by omitting those two handler methods:

public void Test1()
{
    var worker = new MyWorkingComponent2(
        (sender, resultData) => { Console.WriteLine("Result:" + resultData); },
        (sender, progress, someData) => { Console.WriteLine(progress + ":" + someData); return true; }
    );
    
    worker.StartWork();
}

Alright, this would have been possible with events as well if you used anonymous methods. But Visual Studio guides you otherwise and early examples of anonymous methods (before we had lambdas) where rather ugly, so I doubt that can be seen as valid counterargument. Here however lambdas can be seen as typical means of choice.

Verdict

Neat? Net result:

  • I’m writing less code on the event source side, including no longer declaring EventArgs classes.
  • I’m writing less code on the event sink side.
  • The handler methods can use clean parameter lists (rather than EventArgs).
  • I’m eliminating the risk of forgetting to register event handlers by making the callbacks explicit parameters.
  • I’m elimination the danger of leaks due to failing to consistently deregistering event handlers.
    • (That was not addressed in the example, but still.)
  • When chaining together several of these steps I can make the logic – especially conditional processing – more explicit and concise.
    • Events would either require setting up beforehand (partly unnecessary overhead), or setup on demand, cluttering the handler with registration and deregistration code.

All in all, this is way more readable, way more robust, and way more efficient than using events.

I for one have begun to adopt this scheme quite liberally. My Silverlight bookshelf application has wrappers for service calls that translate the event to callbacks (several actually, including error handling and other demands). My dialogs always take callbacks for OK and Cancel. I so far have two ICommand implementations, both take callbacks (one with parameters, the other without). I even have a PropertyObserver class that translates a PropertyChanged event into a callback.
Actual event handlers? Apart from the wrappers enabling what I just presented, only a few reacting to control events.

In other words: This is not just an interesting technical detail. It really changes the way I’m addressing certain demands.

That’s all for now folks,
AJ.NET

kick it on DotNetKicks.com

July 18, 2010

Employment of Events is changing…

Filed under: .NET, .NET Framework, C#, Silverlight, Software Development — ajdotnet @ 3:27 pm

The other day I had a little chat with a colleague. It was about one of his worker components and how it used events to communicate intermediate state and the final result. About event registration and deregistration, and the ungainly code resulting from it. When I suggested using callbacks instead of events, he quickly jumped on the bandwagon; a few day later I got a single note on Messenger: „Callbacks are WAY COOL!“.

That got me thinking. Why did I recommend callbacks? When and why did I abandon events? What’s wrong with events anyway?

Well, there’s nothing wrong with events at all. It’s just that Silverlight, asynchronous, and multithreaded processing have changed the picture (and I may have worked too much in those areas lately 😉 ). And this is the deal:

  1. Until recently I used to “see” (read: write code for/against) events mainly from the event consumer side. WinForms, WebForms; register handler, react to something. That kind of stuff.
    • Since “recently” I kind of had to do that less often. Why? Silverlight data binding solved many of the demands I previously used to address with event handlers. Making a control invisible for example. (Events still drive databinding, but at the same time databinding shields them away from me.)
  2. Also since “recently” I have had to implement the providing part quite a bit more often. Why? Silverlight databinding relies on certain interfaces that contain event declarations, namely INotifyPropertyChanged, INotifyCollectionChanged, and INotifyDataErrorInfo.
  3. And the “event-based asynchronous pattern”. Yep. We’ll get to that one.

OK, let’s try to classify these scenarios.

Broadcasts

The first two points are just two sides of the same coin: The radio broadcasting scenario.

  • Some component wants to advertise interactions or state changes; hence it broadcasts them by way of events.
  • Some client code needs to get notified about one or the other of these events; hence it subscribes to the event by way of an respective event handler, to consume it from there on.

Same as radio, the broadcaster broadcasts and doesn’t care whether anyone listens. Same as radio, the receiver is turned one and listens as long as something comes in. Well, the analogy stops at the life time: Event source and consumers tend to have similar life time.

Passing the Baton

The 3rd point is actually a quite different scenario: Start some work and have an event notify me about the result (and sometimes about intermediate state). Once I receive the result I let go of the participant and pass the baton on to the next piece of work.

Same as in a relay run, each participant does one job and once it’s done, he is out of business. Same as in a relay run, participation is obligatory – take someone out (or put something in his way) and the whole chain collapses.

Needless to say that this is nothing like the broadcasting scenario…

Usually the reason for the event approach (rather than simple return values) is asynchronous processing; and in fact this is not a particularly new pattern – BackgroundWorker works accordingly. On the other hand the pattern is still evolving, as the usual pattern for asynchronous work has been no pattern at all (i.e. leave it to the developer, as Thread or ThreadPool do), or the IAsyncResult pattern (relying on a wait handle). New developments however start to employ events more often, and Microsoft has actually dubbed this pattern as “event-based asynchronous pattern” (see MSDN).

One area which relies heavily on this pattern is server requests in Silverlight, via WebClient or generated proxies. But it doesn’t stop there, as Silverlight is asynchronous by nature, rather than by exception: Showing a modal dialog, navigating to another page, (down-)loading an assembly. And quite often these single incidences are chained together to form a bigger logical program flow, for example:

  • The user clicks the delete button –> the application shows the confirmation dialog –> a call to the delete operation is made –> IF it succeeds (the code navigates to a list page –> …) OTHERWISE (an error message box is shown –> …)

Any arrow represents an event based “hop” to bridge some “asynchronicity gap” – essentially turning the logically sequential chain into a decoupled, temporary register and deregister event nightmare.

Coming back to the beginning of the post: This is the scenario I was discussion with my colleague. And doing this with a whole bunch of events and respective handler methods is simply awkward, especially if you even have to provide the event sources, usually with respective EventArgs classes. And the issue of having to consistently deregister the event handlers in order to avoid memory leaks becomes more prevalent.

Changing the Picture…

Inevitably I got annoyed with the setup/teardown orgies, and eventually I began to abandon events in this case and started passing simple callbacks along. Like this:

void DeleteBook(Book book)
{
    string msg= "Delete book #" + book.Inventory + ", ‘" + book.Title + "’ ?" ;
    MessageBoxes.Instance.ShowConfirm(null, msg, 
        ok => { if (ok) BeginDeleteBook(book); }
    );
}

void BeginDeleteBook(Book book)
{
    this.DeleteBookCall.Invoke(book.BookID,
        ea => NavigateToBooks());
}

And actually I’m not the only one following this approach. The Task Parallel Library TPL for example has already started to make heavy use of callbacks. So this is definitely not limited to Silverlight…

Note: Also this lays the ground for a next evolutionary step: Coroutines.

Caliburn has a nice example of what this looks like; a little weird at first glance actually, but it collects all that logically sequential but technically asynchronous control flow in one method. Jeremy digs a little deeper into the topic in his post “Sequential Asynchronous Workflows in Silverlight using Coroutines”. 

Anyway, even without going into coroutines, the callbacks over events approach has its merits in terms of coding efficiency. I’ll provide a motivating example, next post.

That’s all for now folks,
AJ.NET

kick it on DotNetKicks.com

Create a free website or blog at WordPress.com.