Приложение Windows-Mobile не будет работать после закрытия диспетчером задач - PullRequest
0 голосов
/ 17 марта 2010

Я унаследовал некоторый код Windows-Mobile, который обновлял. Я натолкнулся на странную ошибку, и я надеялся, что хотя она и немного расплывчатая, возможно, она пробудит чью-то память:

Запустив приложение (которое в основном является прославленным приложением Forms с g / кодом P / Invoke), я переключаюсь на диспетчер задач и закрываю приложение с помощью End Task. Кажется, что выход в порядке (без ошибок и исчезает из диспетчера задач). К сожалению, приложение отказывается запускаться во второй раз, пока я не перезагружу телефон или не переустановлю CAB.

Что еще хуже: эта ошибка воспроизводима на HTC Diamond, но работает нормально (т.е. может снова запуститься после EndTask) на HTC HD2.

Единственное, о чем я могу думать, это какая-то временная гонка между Dispose () и диспетчером задач. Есть идеи?

Я также думаю об обходном пути - у меня есть рабочая подпрограмма «Выход из приложения», которая корректно очищает приложение; я могу перехватить событие EndTask в коде c #, чтобы выполнить надлежащую очистку?

Может быть, я просто упускаю болевую точку ... все идеи приветствуются:)

Ответы [ 3 ]

4 голосов
/ 17 марта 2010

Когда вы используете TaskManager, чтобы закрыть его, происходит следующее:

  1. Формы для приложения отправляются сообщения WM_CLOSE
  2. Если по истечении некоторого времени они все еще работают, TerminateProcess используется.

Если у вас запущен рабочий поток, который не завершается, процесс часто завершается не полностью. Это было действительно распространено в CF 1.0, где свойство IsBackground для потока не существовало.

Поскольку TaskManager перечисляет только подписи к формам, если все ваши формы закрыты, приложение не будет отображаться даже после запуска процесса. Когда вы пытаетесь выполнить снова, оболочка обнаруживает, что она уже запущена, и просто переключается на запущенный процесс (без пользовательского интерфейса), поэтому похоже, что ничего не произошло.

Вы можете проверить это поведение с помощью Remote Process Viewer.

Решение состоит в том, чтобы исправить код вашего рабочего потока для правильного выхода. Обычно я использую логическое значение или WaitHandle, чтобы сигнализировать, что они должны выйти. Установка IsBackground в true также должна происходить для всех создаваемых потоков.

1 голос
/ 25 марта 2011

Прошел год с момента вашего вопроса, но это может быть ответом.

У меня была такая же проблема. Мое приложение имеет MinimizeBox = False, это показывает маленький Ok в правом верхнем углу формы и является единственным способом обработки события закрытия (крестик с MinimizeBox = True не вызывает ClosingEvent). В этом случае я отменяю закрытие и создаю некоторый пользовательский код и минимизирую форму, чтобы она выглядела как стандартное поведение «Перекрестная близость».

Проблема в том, что на htc diamond, когда вы убиваете задачу, она вызывает то же самое закрывающее событие, и мой код отменяет его снова. Странно то, что в диспетчере задач приложение исчезло, но если вы запустите исходный диспетчер задач Microsoft (/windows/taskmgr.exe) и в меню выберите «Показать процессы», вы увидите, что ваше приложение все еще работает. Вот почему вы не можете запустить его снова. Странно, но на HD2 он работает так же, как и с событием закрытия, но, похоже, также вызывает грубое уничтожение приложения, поэтому никаких проблем.

Решение: Вам просто нужно немного bool, чтобы узнать, находится ли ваше приложение на переднем или на заднем плане, для которого вы установили значение 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);
    }
}
0 голосов
/ 17 марта 2010

Я не знаю точно, в чем ваша проблема, но я считаю, что устройства WinCE, как правило, позволяют запускать только один экземпляр приложения одновременно. Это может означать, что либо TaskManager не очистил приложение должным образом, поэтому он считает, что оно все еще работает, и не запускает другую копию, ИЛИ, возможно, оно все еще работает.

Попробуйте добавить в приложение код, который определяет, запущено ли оно. Также попробуйте дважды проверить, правильно ли вы очищаете все, когда оно существует, особенно потоки и т. Д., Поскольку время закрытия окон вашего приложения может отличаться от того, как вы делаете это вручную.

Надеюсь, что все это поможет

...