Wednesday, November 19, 2008

That One's A "True"

I love it when people come in (e.g. via email) and describe a "problem" that actually boils down to a description of how the system works.

For us, going over the project's Open Items List, this was a routine part of the triage of incoming items we saw for the first time.

So is that a defect? A feature request?

Nope, it's a True. They have made a correct statement about the operation of the system.

There's a mismatch somewhere though, usually in the user's understanding of the system, their expectations of the system in the particular scenario they encountered, etc.

Sometimes the answer would be "Thanks for describing how the system works; Next!" Typically, we would collect up all the "trues" at the end, and for some, determine some follow-up questions, which would hopefully lead us in a direction that would help understand how the system failed the user.

Friday, November 14, 2008

If I See Another NullPointerException I'm Gonna Yak!

Thursday, November 6, 2008

Are You Using Threads For Everything Yet?

Well, Are You!?

Here's an A-number-one reason for you, Joe: your application's perceived start-up time will kick the Major Ass!

Chances are even good that it will be real start-up time.

This is especially true when you have partitioned your UI "correctly" say, as plugins, and in your main form's start-up, you need to iterate all the loaded plugins and invoke the lifecycle start method, say ILifecycle.Start().

If we have a reasonable number of plugins, i.e. UI elements, the whole startup process bogs down in serial processing of everyone's startup. This typically invokes User Gak Syndrome, as your form appears, if at all, as a big, unrefreshed rectanglular glob on the screen.

Using the Windows Forms environment, this means that the ThreadPool, anonymous delegates, and Control.Invoke() are your newest, bestest buddies! No amount of work is too small to do anywhere but the UI thread!

I speak from experience, because I transformed my very own application to use increased background processing, and that biach snaps right up on the screen!

Before the transformation, start-up was becoming noticably slower, to the point of you could see each section refresh. Some other refresh cycles were also causing some noticable flashing, because some "inocuous" processing was trapped on the UI thread between BeginUpdate() and EndUpdate().

Since perception is everything, this approach gives your main form the opportunity it needs to get up on the screen and refreshed as fast as possible, without all of the initialization bogging it down.

So, to recap: in all of your startup and UI event handler responses:

  1. Take advantage of anonymous closures to capture all the context you need to do your processing and UI binding.
  2. Make a closure that will handle the UI binding. This gets used in Control.Invoke().
  3. Make a closure that does the work, then calls Control.Invoke() with the first closure. Use the UI element you are targeting in the call.
  4. Run the second closure on the ThreadPool or dedicated Thread.
  5. Get off the UI thread! There's more work to do....

Disclaimer

Look, this is humor, so put away the flame-thrower! Just have a laugh and go on your merry way....