0

私は、最新のものにしてきたいくつかの Windows モバイル コードを継承しました。私は奇妙なバグに出くわしました.少し漠然としていても、誰かの記憶に火をつけるかもしれないと思っていました:

アプリ (基本的には、P/Invoke gps コードを使用した美化されたフォーム アプリ) を実行し、タスク マネージャーに切り替えて、[タスクの終了] でアプリを閉じます。正常に終了したようです (エラーはなく、タスク マネージャーから消えます)。残念ながら、電話を再起動するか CAB を再インストールするまで、アプリは 2 回目の起動を拒否します。

さらに悪いことに、このバグは HTC Diamond で再現可能ですが、HTC HD2 では正常に動作します (つまり、EndTask の後で再度実行できます)。

私が考えることができる唯一のことは、Dispose() とタスク マネージャーの間のある種のタイミング競合です。何か案は?

回避策も考えています。アプリを正しくクリーンアップする「アプリケーションの終了」ルーチンが機能しています。適切なクリーンアップを完了するために、C# コードで EndTask イベントをキャッチできますか?

多分私は問題点を見逃しているだけです...すべてのアイデアを歓迎します:)

4

3 に答える 3

4

TaskManagerを使用して閉じると、次のようになります。

  1. アプリフォームはWM_CLOSEメッセージを送信します
  2. 一定期間が経過してもまだ実行中の場合は、TerminateProcessが使用されます。

終了しないワーカースレッドを実行している場合、プロセスは完全に終了しないことがよくあります。これは、スレッドのIsBackgroundプロパティが存在しなかったCF1.0では非常に一般的でした。

TaskManagerはフォームのキャプションのみを列挙するため、フォームがすべて閉じている場合、プロセスが実行されていてもアプリは表示されません。再度実行しようとすると、シェルは既に実行中であることを検出し、実行中の(UIなしの)プロセスに単純に切り替えて、何も起こらなかったように見えます。

この動作は、RemoteProcessViewerで確認できます。

解決策は、ワーカースレッドコードを修正して正しく終了することです。通常、ブール値またはWaitHandleを使用して、終了する必要があることを通知します。IsBackgroundをtrueに設定すると、作成されるすべてのスレッドでも発生するはずです。

于 2010-03-17T12:58:11.247 に答える
1

あなたの質問から1年が経ちましたが、これが答えかもしれません。

私は同じ種類の問題を抱えていました。私のアプリには MinimizeBox = False があります。これはフォームの右上隅に小さな OK を示し、Closing Event を処理する唯一の方法です (MinimizeBox = True の Cross は 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 デバイスでは、アプリケーションの 1 つのインスタンスしか一度に実行できない傾向があることがわかりました。これは、TaskManager がアプリケーションを適切にクリーンアップしなかったため、アプリケーションがまだ実行中であると認識して別のコピーを開始しないか、または実際にはまだ実行中であることを意味する可能性があります。

アプリケーションが既に実行されているかどうかを検出するコードをアプリケーションに追加してみてください。また、ウィンドウがアプリケーションをシャットダウンするタイミングは、手動で行う場合とは異なる場合があるため、存在する場合はすべて、特にスレッドなどを適切にクリーンアップしていることを再確認してください。

それが役立つことを願っています

于 2010-03-17T11:37:55.653 に答える