Welcome to CrankyGoblin.Com Sign in | Join | Help

Public Class GeoffAppleby

Inherits Microsoft.VisualBasic.MVP : Implements IBrainFart
How does Advanced mean 'Find the easy way'?

Today I discovered that the March edition of MSDN magazine had appeared online. This is generally a good thing, and if I can find the time to have a read, then I do. I was particularly interested in this one, since it's about web services - something near and dear to my heart, even tho I'm nowhere near an expert.

So I had a flick through the articles (yes, I do actually read it for the articles in this case, strange as that is for me), and I stumbled across one that was not so much to do with web services as it was plain old async, and in particular WinForms dealing with getting large processing jobs done asynchronously so that it doesn't lock up the GUI.

I figured it was going to simply deal with Invoke and Begin/End-Invoke on Controls (and it did), but instead I was actually quite disappointed.

You see, in theory what the article was trying to show was fine. Basically it went like this:

  1. Here's an app that locks up for a long time when you click a button.
  2. Now here's the same app, but it doesn't lock up. But it's bad, because, it updated controls from the non-GUI-thread.
  3. Now here it is doing it the right way, using Invoke.
  4. Now here's what you can do in Whidbey - use the background worker!

One thing it really needed (and it was sorta mentioned that not everything was covered due to space limitations) was a step between 3. and 4. that talked a little about BeginInvoke and EndInvoke.

But this isn't really my problem. My problem was the way in which the background worker was used.

The background worker is a great little component. It's a nice easy way to do some work in background (duh!). It's nice because you don't have to do any of the thread management yourself - you just give it a method to run, and it raises an event when it's done - and the event is raised on the thread that kicked it off in the first place. In a WinForms app, that'd be the GUI thread.

It also has a ProgressChanged event that let's you signal back to the parent thread what stage it's at. Generally you'd pass through a percentage, so you could update a progress bar (for example).

But this article is using the ProgressChanged event to pass through extra data - which is fine, the model has provisions for it by setting a UserState object on the ProgressChangedEventArgs. This can be used to pass any data, it's only of type Object afterall, but surely the point of the property is to pass through an identifier of some sort so you can be sure of which background worker you're using?

Maybe it's just me, but the whole point of an event like this is to a) notify the parent that some progress has been made (and there's provisions to provide an exact percentage, if you wish), and b) use arguments on this event to identify just which child thread is calling you, so you know what has made progress.

Using it as a data pump feels immensely wrong. To me, this gets filed with the good old 'Tag' property that we abuse over and over again. And what gets my goat is that this idea is presented under the headings of 'Advanced Basics'. This isn't advanced - this is just continuing to add to the stigma attached to us VB developers that we can't really program, and that we take shortcuts and use inefficient solutions. What this guy has done has shown people how to manipulate things in ways that I feel they were never intended.

Some sort of callback needs to be made to the GUI to get it updated on the GUI thread, sure. But I'd certainly prefer to write a new class that inherits from the background worker, and either provide another event to pass through eventargs of a better format to keep it clear exactly what was being passed (read: strong typing is GOOD!), or require a delegate to passed in to forward on a custom call (which then need to perform an Invoke/BeginInvoke as required) or even combine that with requiring some control to call Invoke/BeginInvoke on internally so that perhaps the delegate is already invoked on the parent thread anyway. (I'm not sure I've described that too well. I know what I mean, and that's more than enough :) Basically, extend the background worker to encompass the extra calls you need to make.

Mostly it just doesn't feel right. There's a number of different ways to do this properly, but I feel dirty when I think about doing it this way.

But what do the rest of you think? Do I feel dirty for a good reason? Should I be ranting, or getting back in my box and hiding?

Listening to: breakdown - guns n roses - (7:04)
Posted: Saturday, 26 February 2005 12:12 AM by Geoff Appleby
Filed under: ,

Comments

TrackBack said:

# March 14, 2005 12:58 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

To submit your comment, click on these pictures:
  • Super Geoff!
  • Geoff's bald spot
  • Geoff's dad's tongue
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Gaptcha Image - No Peeking! Gaptcha Image - No Peeking! Gaptcha Image - No Peeking!
Can't recognise the people in these pictures? Look here for a quick introduction.
There's a time limit for you to get your comment submitted before this set of pictures expires. If you think it's been longer than 10 minutes, get some new pictures first (you won't lose what you've typed so far).
Get some new pictures 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS