views:

169

answers:

1

I have a Windows Mobile program that accesses an attached device through a third-party DLL. Each call to the device can take an unknown length of time, so each call includes a timeout property. If the call takes longer than the specified timeout to return, the DLL instead throws an exception which my app catches with no problem.

The problem that I have is with closing the application. If my application has made a call to the DLL and is waiting for the timeout to occur, and I then close the application before the timeout occurs, my application locks up and requires the PDA to be rebooted.

I can ensure that the application waits for the timeout before closing, under normal conditions. However, I am trying to use AppDomain.CurrentDomain.UnhandledException to catch any unhandled exceptions in the program and use the event to wait for this pending timeout to occur so the program can be closed finally.

My problem is that this event doesn't seem to stick around long enough. If I put a MessageBox.Show("unhandled exception"); line in the event, and then throw a new unhandled exception from my application's main form, I see the message box for a split second but then it disappears without my having clicked the OK button.

The documentation I've found on this event suggests that by the time it's called the application is fully committed to closing and the closing can't be stopped, but I didn't think it meant that the event method itself won't finish. What gives (I guess that's the question)?

Update: In full windows (Vista) this works as expected, but only if I use the Application.ThreadException event, which doesn't exist in .Net CF 2.0.

+2  A: 

I came across this problem as well. This is a known issue in .NET CF (v2.0), but I also had it while using v3.5 (although the situations in which it occurs are more specific). You can find the (old and still active) bug report here.

Calling MessageBox.Show() causes it to close immediately, but in my case there were two workarounds: 1) Call the MessageBox.Show() a second time. It then does block until closed by the user. You can check the first MessageBox.Show() closed prematurely by checking the DialogResult. I don't remember which result it returned exactly when it failed, I remember it giving a non-default result.

2) Create a custom Form and call ShowDialog() on that. It worked for me, but others have reported it doesn't work. You could also call Show() and make it blocking yourself (don't forget to call Application.DoEvents() so it keeps processing events).

Martijn Stolk