Mike’s Dump

January 20, 2006

The Test Never Lies

Filed under: Links — mikesdump @ 3:08 pm

Mr. Tech Embassy pointed this test out and it provided me a couple minutes of
entertainment.

Come on, you know you have to try it


Your Blogging Type Is Thoughtful and Considerate


You’re a well liked, though underrated, blogger.
You have a heart of gold, and are likely to blog for a cause.
You’re a peaceful blogger – no drama for you!
A good listener and friend, you tend to leave thoughtful comments for others.

What’s Your Blogging Personality?

Advertisements

.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!

January 15, 2006

.NET Compact Framework – Updating the User Interface from a Worker Thread

Filed under: Code — mikesdump @ 12:06 pm

Before you go ahead and update the UI from another thread using the .NET Compact Framework ask yourself the following:

“Self, do I like predictability or unpredictability?”

If you answered predictability then you can skip ahead to “What you should do after you got it wrong”. If you answered unpredictability then proceed to “Don’t be a moron, Mike already tried that”

Don’t be a moron, Mike already tried that
In my own defence I didn’t realize at the time the event was firing from a thread outside the main UI thread (I’m not sure if that is much of an excuse)

Anyways, you like unpredictability eh? I’m guessing when you are updating your UI from a worker thread you are doing something like this:

Private workerThread As Thread
Private shuttingDown As Boolean

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
workerThread = New Thread(AddressOf UpdateUIFromWorkerThread)
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 UpdateUIFromWorkerThread()
Dim counter As Integer


While shuttingDown = False
Label1.Text = counter.ToString()
counter += 1
Thread.Sleep(500)
End While

End Sub

What is happening here is a worker thread is created when this CE application first starts. The thread enters a loop that won’t end until the form is closed. In the loop a label is updated with the value of a counter which is incremented every half second.

When I tried this in the emulator it actually is predictable. Both attempts locked up the emulator and I wasn’t able to shutdown the application. I’ve seen more complicated applications updating the UI from a worker thread that weren’t so consistent.
In short, don’t update the UI from outside the main UI thread. UI controls are not thread safe.

What you should do after you got it wrong
There are many things you should be doing after getting it wrong the first time. The key to getting it right is completing the steps below in order.

1) Swear at your computer and/or CE device
2) Grab another beer (if you aren’t currently drinking that is another mistake)
3) Read the right freak’in documentation

Sure, you are thinking this is a simple problem. I just need to use that “control.invoke” thingy and all will be well. The answer is yes and no. The compact framework way is below.

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

There are only a couple small changes from the previous version of this code.

1) counter is no longer a local variable to the worker thread method (UseInvokeInsteadOfDirectlyUpdatingUI())
2) The worker thread method calls Me.Label1.Invoke which will call WorkerThreadPlayingNiceWithTheUI
3) WorkerThreadPlayingNiceWithTheUI uses the member level variable counter to update the label.

What gave me a little bit of grief was I was reading a post I found on invoke which would be fine for the desktop but didn’t work in the compact framework (I can’t recall for sure but I believe I got an ArguementException when attempting it this way).

On the desktop the invoke method is overloaded and you would be able to pass the value of “counter” to the method directly instead of making it a member variable. I would prefer this over declaring the counter at the class level but it doesn’t appear to be an option for the compact framework.

The second thing that got me is that the delegate must be of type EventHandler for the compact framework (also this is something this post told me not to do).

The last item to note in the MSDN documentation which I don’t think applies in this case is:

An important point to note is that you must call Application.DoEvents() in your code if you are updating the UI in the worker thread. Calling Application.DoEvents() will make sure that any events raised by the worker thread are processed by the UI thread.

Looking at the example on that page the UI thread was blocking for one second. Just before the sleep call it was calling Application.DoEvents() which would process any events waiting to be processed by the worker thread. Since in my example the UI thread isn’t blocking at any point the Invoke calls are completed as expected.

The moral of the story: Don’t just read the documentation, read the right documentation.

kick it on dotnetkicks.com

System Error &H80070005&

Filed under: Code — mikesdump @ 2:20 am

I was getting this really odd error when compiling a smart client application in VB.NET the other day.

system Error &H80070005&

I was just about to access my long term memory to try
and figure out the problem when I thought, “Hey , I just checked all of
this out of VSS perhaps something is read only that shouldn’t be”.

Sure enough, all the files in the bin and obj directories were checked
into VSS with the project. When I checked them out they were all read
only and the compiler couldn’t overwrite the files. You’d think VS.NET
would give a bit better of an error message though.

January 7, 2006

Stop the Insanity! Windows Explorer Integrated Unzip

Filed under: Home — mikesdump @ 6:22 am

For the most part I like Windows XP. The stability, from my experience,
has improved slightly over Windows 2000 and by leaps and bounds over
Windows 98 (I never bother trying that Windows ME crap).

With each version of Windows there are new “features” here and there.
Sometimes you have control over these features and other times your
control is limited. My current complaint is the built decompression of
zip files in Windows Explorer. This “feature” drives me nuts because
Windows Explorer can appear to hang in two cases.

1) Many zips in a single folder
For simplicity everything I download I put into the same folder. After
a while I collect several zip files in this folder because I’m unsure
if I want to keep the file or perhaps I’m holding on to it until I burn
a CD. Navigating to this folder when it has 5 or more zip files is
painfully slow. I might as well select the folder and go get a beer� at
a pub� in Calgary
.

2) Large zips
I run a weekly backup on my laptop and the last part of the process is
to compress everything into a single zip. This backup is normally about
700 MB. Opening a folder, which contains a 700 MB zip in Windows
Explorer is just a frustrating as a folder with several smaller files.
The only positive that comes out of this is, again, this is a fine time
to go get a beer.

This feature might not be all evil if there were a couple options.
First give me the option to disable this functionality altogether.
Second, give me an option to only decompress when I try to open the
file not as soon as I open the folder.

The Solution?
You resort to the hack of course. I found this post a little
while ago, which allowed me to disable this functionality.

You can disable XP’s zip file support using regsvr32, a tool that
allows you to register or un-register object linking and embedding
(OLE) controls. Follow these steps to disable this feature:

Select Run from the Start Menu.
Type “regsvr32 /u %windir%\system32\zipfldr.dll” at the prompt.
Click OK.

The change will take effect immediately, but you may have to restart
Windows for all traces of the built-in ZIP support to disappear. After
restarting your system, your problem should be solved, but you may need
to reassociate your unzipping program (WinZip, etc.) with the files
before you can view and open them.

If you want to re-enable Windows XP’s built-in ZIP support, just follow these steps:

Select Run from the Start Menu.
Type “regsvr32 %windir%\system32\zipfldr.dll” at the prompt.
Click OK.

I did this a couple times with a reboot in-between to get rid of this functionality.

Blog at WordPress.com.