About the author

Brian Keating is a developer addicted to Microsoft Technologies.

Month List

RecentComments

Comment RSS

Converting EPM operations to Tasks using the TPL

clock February 5, 2012 11:41 by author Brian Keating |

 

Previous post

Overview

The Event Programming Model (EPM from her on in) was introduced in .NET 2.0, it’s purpose was to serve as a simpler pattern for asynchronous operations than the Asynchronous Programming Model (APM / IAsyncResult, see my previous post on APM) where possible, mostly in UX code. Methods that use this pattern typically end in Async and have a Completion event.

The best known implementation of the EPM is the BackgroundWorker component, it’s got a distinct advantage in that it tries to use a synchronization context to fire the event on the thread from which it was called, the APM on the other hand offers no such guarantee.

Let’s see this in action (.net 4.0)


image

What you can see in the snippet above is a simple windows form (been a while my old friend) application. Let me paint you a picture, it’s early February 2012 and I’m stuck here at Brussels international airport, in the middle of a snow blizzard wondering if I’m going to have a flight home. The plane that will take me there is arriving in from Dublin so I’m looking at the live departures to see if it’s departed (already 15 mins late darn it.. ) anyway back to the post at hand; I’m downloading the page html with the call to DownloadStringAsync(), you can see in the completion event handler that I’m not doing any Invoking (dispatching to those of you that never had the pleasure of windows forms).

Now this is what it looks like after the event gets fired.

image

hey and looks like it’s running MS tech (notice that viewstate, incase the .aspx didn’t give it away!) nice! If you come from a web background this may not seem that odd to you, but if you started out desktop application development like me there was one golden rule you never forgot and that’s that always talk to the GUI in one thread and one thread only.

If the event handler wasn’t in the GUI thread above we would have received a cross thread exception like this:

image

 

Sadly TPL doesn’t handle the EPM as easily as the APM specifically in respect to the synchronization context, but lets see how we approach it, you may have to if you’re pre .net 4.0 as the DownloadStringAsync doesn’t exist!

image

With the code above we hit the cross-thread exception problem. We could do a Control.BeginInvoke (or Dispatcher.BeginInvoke in WPF), but lets imagine we were writing a library and we wanted it to be framework agnostic, how would we do this?

Actually it’s pretty simple, we just supply a context like this:

image

p.s. I got home at 4am Sad smile




Converting APM operations to Tasks using the TPL

clock January 1, 2012 12:47 by author Brian Keating |

 

Those of you have have already used .net 4.5 developer preview will know that tasks are becoming more common in the API, especially with the advent of the async await keywords.

But many of you (including me) can’t really advocate .net 4.5 in the enterprise so what are our options should we like to use the TaskParallelLibrary?

As you may be aware APM (Asynchronous Programming Model) was the original .NET mechanism for handling Async operations, it will be familiar to you as the IAsyncResult pattern.

So lets take a common operation of reading from a stream, in .net 4.5 we already have a Stream.ReadAsync, but again what if we don’t have .net 4.5 at our disposal?

The task parallel library helps bridge the gap with Task.Factory.FromAsync, here I place it in an extension method for ease of use.

image




Synchronize you controllers when necessary

clock December 4, 2011 15:11 by author Brian Keating |

Earlier today I happened to lend a hand to a friend of mine that was experiencing a race condition in an ASP.MVC application, like a rag to a bull is multithreading to me.

Here’s the scenario; my friend was calling two web services using methods like BeginXXX/EndXXX. Because her website was IO bound she was correctly using an AsyncController.

She called method to increment the outstanding operations by 2, then proceeded to call

service1.BeginGetValuations(v, ar => {
    AsyncManager.Parameters["valuations"] = service1.EndGetValuations();
    AsyncManager.OutstandingOperations.Decrement();
}, null);
    
service2.BeginGetValuations(v, ar => {
    AsyncManager.Parameters["valuationsActual"] = service2.EndGetValuations();
    AsyncManager.OutstandingOperations.Decrement();
},null);

 

Looked pretty much ok, except once in a while when load tested the valuationsActual parameter was null.
So what could be the cause… Well basically it turned out that there was a race condition accessing the dictionary from two threads.

The solution:

synchronize access to the Parameters, i first thought of doing this with a plain old lock but I was worried about other access on the parameters from the framework itself so I had a quick read of the documentation and turns out that the AsyncManager has a sync method.

 
service1.BeginGetValuations(v, ar => {
    AsyncManager.Sync(() => {
        AsyncManager.Parameters["valuations"] = service1.EndGetValuations();
        AsyncManager.OutstandingOperations.Decrement();
    });
}, null);
    

Do the same for service2.




Syncronization Context

clock September 8, 2010 21:17 by author Brian Keating |

A sample of using SyncronizationContext to post a message back to the UX thread

 

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    SynchronizationContext ctx = SynchronizationContext.Current;

    ThreadPool.QueueUserWorkItem(_ =>
    {

        WebClient client = new WebClient();

        string html = client.DownloadString("http://www.briankeating.net");
        ctx.Post(state =>
        {
            tbDetails.Text = (string)state;

        }, html);

    });

}




Silverlight Multithreading and the UI

clock February 21, 2010 21:54 by author Brian Keating |

 

When you wish to know if you are on the UI thread and you've no access to any UIElement how do you do it?

static bool IsUiThread()
{
    return Deployment.Current.Dispatcher.CheckAssess();
}