0

我继承了一些我一直在更新的 windows-mobile 代码。我遇到了一个奇怪的错误,我希望即使有点模糊,也许它会激发某人的记忆:

运行应用程序(它基本上是一个带有 P/Invoke gps 代码的美化 Forms 应用程序),我切换到任务管理器,然后通过 End Task 关闭应用程序。似乎退出正常(没有错误并从任务管理器中消失)。不幸的是,该应用程序拒绝第二次启动,直到我重新启动手机或重新安装 CAB。

更糟糕的是:这个错误可以在 HTC Diamond 上重现,但在 HTC HD2 上工作正常(即可以在 EndTask 之后再次运行)。

我唯一能想到的是 Dispose() 和任务管理器之间的某种计时竞赛。有任何想法吗?

我也在考虑一种解决方法——我确实有一个有效的“退出应用程序”例程,可以正确清理应用程序;我可以在 c# 代码中捕获 EndTask 事件以完成正确的清理吗?

也许我只是错过了痛点......欢迎所有想法:)

4

3 回答 3

4

当您使用 TaskManager 关闭它时,会发生以下情况:

  1. 应用程序表单发送 WM_CLOSE 消息
  2. 如果一段时间后,它们仍在运行,则使用 TerminateProcess。

如果您有一个运行的工作线程不退出,则该进程通常不会完全终止。这在不存在线程的 IsBackground 属性的 CF 1.0 中非常常见。

由于 TaskManager 仅枚举表单标题,因此如果您的表单全部关闭,即使进程正在运行,它也不会显示应用程序。当您尝试再次执行时,shell 检测到它已经在运行,并简单地切换到正在运行的(没有 UI)进程,因此看起来什么也没发生。

您可以使用 Remote Process Viewer 验证此行为。

解决方案是修复您的工作线程代码以正确退出。通常我使用布尔值或 WaitHandle 来表示它们应该退出。对于创建的所有线程也应该将 IsBackground 设置为 true。

于 2010-03-17T12:58:11.247 回答
1

你的问题已经过去一年了,但这可能是答案。

我有同样的问题。我的应用程序有 MinimizeBox = False,这会在表单的右上角显示一个小 Ok,并且是处理关闭事件的唯一方法(带有 MinimizeBox = True 的十字不会引发 ClosingEvent)。在这种情况下,我取消关闭并执行一些自定义代码并最小化表单,使其看起来像标准的“交叉关闭事物”行为。

问题是,在 htc diamond 上,当您杀死一个任务时,它会引发相同的关闭事件,而我的代码会再次取消它。奇怪的是,在任务管理器中该应用程序已经消失了,但是如果您启动原始的 Microsoft 任务管理器 (/windows/taskmgr.exe) 并在菜单中选择显示进程,那么您会看到您的应用程序仍在运行。这就是为什么你不能再次启动它。奇怪的是,在 HD2 上,它与关闭事件具有相同的行为,但它似乎也强制对应用程序进行暴力杀戮,所以没问题。

解决方案:您只需要一点布尔值就可以知道您的应用程序是在前台还是在后台,您在表单激活事件中设置为 true,在停用事件中设置为 false。在关闭事件中,只有当您的应用程序处于前台时您才能取消您可以运行您的特殊代码,否则让表单关闭,这是一个杀戮!

[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);
    }
}
于 2011-03-25T12:50:18.210 回答
0

我不确切知道您的问题是什么,但我发现 WinCE 设备往往只允许一个应用程序实例一次运行。这可能意味着 TaskManager 没有正确清理应用程序,因此它认为它仍在运行并且没有启动另一个副本,或者它实际上可能仍在运行。

尝试在您的应用程序中添加一些代码来检测它是否已经在运行。还请尝试仔细检查是否正确清理了所有内容,尤其是线程等,因为 Windows 关闭应用程序的时间可能与您手动执行的时间不同。

希望任何帮助

于 2010-03-17T11:37:55.653 回答