Mike’s Dump

January 20, 2006

.NET Compact Framework – Updating the UI from a Worker Thread – Part Deux

Filed under: Code — mikesdump @ 2:14 pm

Just when you thought it was safe to enter the water, there it is.
Slowing the music gets louder (you’ll just have to imagine the Jaws
music at this point because I have no idea how to type it).

Then it strikes! BANG � right in the ass. Well, this one does sneak up on you anyways.

Another developer at work was running into a situation where the UI
needed to be updated from another thread but when that happened the
application appeared to lock up. I found it slightly amusing because
the day before I ran into the same problem and I posted my solution
here
.
When he tried the solution and it didn’t solve the problem I was a little confused.

After working with emulators for several years I know they can be buggy
and not like the real thing but I wasn’t ready to throw in the towel
yet. So I turned to my trusty magic wand and
after casting several spells, whala! The one piece of information
required was found here.

So we will start with the code from the previous post, which was a form in a smart client application.

Private workerThread As Thread
Private shuttingDown As Boolean
Private counter As Integer

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
workerThread = New Thread(AddressOf UseInvokeInsteadOfDirectlyUpdatingUI)
workerThread.Start()
End Sub

Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
shuttingDown = True
End Sub

Private Sub UseInvokeInsteadOfDirectlyUpdatingUI()
While shuttingDown = False
Me.Label1.Invoke(New EventHandler(AddressOf WorkerThreadPlayingNiceWithTheUI))
counter += 1
Thread.Sleep(500)
End While
End Sub

Private Sub WorkerThreadPlayingNiceWithTheUI(ByVal sender As Object, ByVal e As System.EventArgs)
Label1.Text = counter.ToString()
End Sub

Now instead of our application directly launching the form on start up
we will create a module with a “main” method (or a class with a
shared/static method) which creates and displays the form like so

Module Module1
Public Sub Main(args() as String)
Dim mainForm as new Form1()
mainForm.ShowDialog()
End Sub
End Module

If you try to run this in the emulator you will probably notice the
label never updates. If you put a break point in just before the
“Me.Label1.Invoke” call and step through the code you will notice the
application will appear to “hang” on the invoke method call. If you run
in debug mode and “pause” the application you will be brought to this
line

mainForm.ShowDialog()

This line is the biggest clue to the real issue. The only thing we have
changed is how the main form is being created right? Well kind of. If
you set the form as the startup object I believe it is doing something
like the following instead behind the scene:

Module Module1
Public Sub Main(args() as String)
Dim mainForm as new Form1()
Application.Run(mainForm)
End Sub
End Module

So what is going on?
ShowDialog does indeed show the form as we would expect but when it is
launched it is modal. From here on in this is all speculation on my
part but I believe the only UI messages that would be processed are
those on the form itself (say if you added a button to the form as
well).
When the invoke method is called it is adding a event message to the
Windows event queue which will be processed after the current method is
completed, which in our case after mainForm.ShowDialog returns. If the
application is started with Application.Run the method returns
immediately and the worker thread’s invoke calls can be processed
immediately.

To sum things up� don’t start the application with ShowDialog. Yep that
would be about it. I’m not really sure why we were doing that to begin
with. Just for the record the developer who is currently working on
this is completely innocent (in all honestly I wouldn’t be surprised if
the code was traced back to me� damn source control)

As I mentioned this is mainly speculation on my part based on what I
have seen. I haven’t read anything to suggest this is indeed what is
happening under the hood.

Comments are welcome!

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: