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 :)
When you use TaskManager to close it, the following happens:
- The app Form(s) are send a WM_CLOSE message
- 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.
it's been a year since your question, but this might be the answer.
I had the same sort of problem. My app has MinimizeBox = False, this shows a small Ok in the right top corner of the form and is the only way to handle the Closing Event (the Cross with MinimizeBox = True doesn't raise ClosingEvent). In this event I cancel the closing and do some custom code and minimize the form so that it looks like the standard ‘Cross close thing’ behavior.
The problem is that on htc diamond, when you kill a task it raises the same closing event, and my code cancels it again. The weird thing is that in task manager the app has disappeared, but if you launch the original Microsoft task manager (/windows/taskmgr.exe) and in the menu select show processes, then you see your app still running. That’s why you can’t launch it again. Strangely on HD2 it has the same behavior with the closing event, but it seems to also force a brute kill on the app, so no problem.
The solution : You just need a little bool to know if your app is on foreground or on background that you set to true in the form activate event and false on deactivate event. In the closing event, you cancel only if your app is in foreground you can run your special code, otherwise let the form close, it's a kill !!!
[DllImport("coredll.dll")]
static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_MINIMIZED = 6;
public static void MinimizeForm(IntPtr pFormHandle)
{
ShowWindow(pFormHandle,SW_MINIMIZED);
}
private bool m_IsFormVisible = false;
void m_MainForm_Deactivate(object sender, EventArgs e)
{
m_IsFormVisible = false;
}
void m_MainForm_Activated(object sender, EventArgs e)
{
m_IsFormVisible = true;
}
void m_MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (m_IsFormVisible)//very important !
{
e.Cancel = true;
//do something if you want
//minimize the form yourself
MinimizeForm(s_Instance.m_MainForm.Handle);
}
}
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
精彩评论