views:

252

answers:

2

I've inherited some windows-mobile code that I've been bringing up-to-date. I've come across a weird bug, and I was hoping that even though a bit vague, maybe it will spark someone's memory:

Running the app (which is basically a glorified Forms app with P/Invoke gps code), I switch to the task manager, and close the app via End Task. Seems to exit fine (no errors and disappears from Task Manager). Unfortunately, the app refuses to start a second time until I reboot the phone or reinstall the CAB.

What's worse: this bug is reproducible on a HTC Diamond, but works fine (ie. can run again after EndTask) on an HTC HD2.

The only thing I can think of is some kind of timing race between a Dispose() and the Task Manager. Any ideas?

I'm also thinking of a workaround - I do have a working "Exit Application" routine that correctly cleans up the app; can I catch the EndTask event in the c# code in order to complete a proper cleanup?

Maybe I'm just missing the pain point... all ideas welcome :)

A: 

I don't know exactly what your problem is, but I find WinCE devices tend to only allow one instance of an application to run at once. This could mean that either TaskManager didn't clean up the application properly so it thinks it's still running and doesnt start another copy, OR, it might actually still be running.

Try put some code in your application that detects if it is already running. Also try double check you are cleaning everything up properly when it exists, especially threads etc as the timing of windows shutting down your application may be different to you doing it manually.

Hope any of that helps

Chris
Thanks Chris for the response. As far as I understand, this indeed the issue: WinCE only allows one instance. So the problem is TaskManager is cleaning up the application differently and I'm in a Catch-22. Since the program never really "exited", I can't start it a second time (so it can't check if it's already running). The app also has no idea it was requested to exit, unless I can somehow catch the TaskManager kill request. I'll double-check the thread cleaning, but I'm hoping maybe there is a way for the app to find out about the TaskManager kill request; otherwise, the app is in the dark.
pithyless
Im not sure if this is viable for you, but what I did with my app was to close it everytime the user went to another screen (pressed cancel, or the form lost focus). This way it ALWAYS exits and starts fresh. Is this something that could help you?
Chris
Unfortunately that's a no-go in my case (background GPS tracking, etc). But I'll just keep digging into the code; hoping to find the "oops" that's causing the timing issues. :)
pithyless
It's not CE that enforces app sinbgleton, it the WinMo shell.
ctacke
@ctacke: right, good clarification. :)
pithyless
+3  A: 

When you use TaskManager to close it, the following happens:

  1. The app Form(s) are send a WM_CLOSE message
  2. If, after a period of time, they are still running TerminateProcess is used.

If you have a worker thread running that does not exit, the process will often not fully terminate. This was really common in CF 1.0 where the IsBackground property for a thread didn't exist.

Since TaskManager only enumerates Form captions, if your forms are all closed, it will not show the app, even through the process is running. When you try to execute again, the shell detects that it's already running and simply swithes to the running (with no UI) process so it looks like nothing happened.

You can verify this behavior with Remote Process Viewer.

The solution is to fix your worker thread code to exit properly. Typically I use a boolean or a WaitHandle to signal that they should exit. Setting IsBackground to true should also happen for all threads that are created.

ctacke
Thanks, this has put me on the right track. I think I fixed the threading issue.. but on a similar issue: if my main form spawns a ShowDialog() and we at this point close the app via TaskManager; we invoke the Closing event on the child form. Now, if I don't tell the child form to close the rest of the app, I get back to the original bug. On the other hand, running Aplication.Exit() means the app will always exit (even if all I want to do is close the child form). Both solutions seem as silly to me - how can my child form know that the Close event is from TaskManager or clicking top-right "OK"
pithyless
apparently now my cure is deadlier than the disease (for child forms). And to mention, this is a problem on the HTC Diamond; the HTC HD2 works just fine. I'm at odds how I should go about fixing this...
pithyless