Приложение Windows-Mobile не запускается после закрытия диспетчером задач

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

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

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

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

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

Может, мне просто не хватает болевой точки ... все идеи приветствуются :)


person pithyless    schedule 17.03.2010    source источник


Ответы (3)


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

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

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

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

Вы можете проверить это поведение с помощью средства просмотра удаленных процессов.

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

person ctacke    schedule 17.03.2010
comment
Спасибо, это привело меня на верный путь. Я думаю, что исправил проблему с потоками ... но по аналогичной проблеме: если моя основная форма порождает ShowDialog (), и на этом этапе мы закрываем приложение через TaskManager; мы вызываем событие Closing в дочерней форме. Теперь, если я не скажу дочерней форме закрыть остальную часть приложения, я вернусь к исходной ошибке. С другой стороны, запуск Aplication.Exit () означает, что приложение всегда будет выходить (даже если все, что я хочу сделать, это закрыть дочернюю форму). Оба решения кажутся мне такими же глупыми - как моя дочерняя форма может узнать, что событие Close исходит из TaskManager или щелкнуть в правом верхнем углу OK - person pithyless; 17.03.2010
comment
видимо теперь мое лекарство смертельнее болезни (для детских форм). Кстати, это проблема HTC Diamond; HTC HD2 работает нормально. Я не понимаю, как мне это исправить ... - person pithyless; 17.03.2010

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

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

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

Решение: вам просто нужно немного bool, чтобы знать, находится ли ваше приложение на переднем плане или в фоновом режиме, для которого вы установили значение true в событии активации формы и false при событии deactivate. В событии закрытия вы отменяете, только если ваше приложение находится на переднем плане, вы можете запустить свой специальный код, в противном случае пусть форма закрывается, это убийство !!!

[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);
    }
}
person ylgstudio    schedule 25.03.2011

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

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

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

person Chris    schedule 17.03.2010
comment
Спасибо Крису за ответ. Насколько я понимаю, это действительно проблема: WinCE допускает только один экземпляр. Итак, проблема в том, что TaskManager очищает приложение по-другому, а я нахожусь в Catch-22. Поскольку программа так и не завершилась, я не могу запустить ее второй раз (поэтому она не может проверить, запущена ли она). Приложение также не знает, что было запрошено выйти, если я не смогу каким-то образом уловить запрос на уничтожение TaskManager. Я дважды проверю очистку потоков, но я надеюсь, что у приложения есть способ узнать о запросе на уничтожение TaskManager; в противном случае приложение остается в темноте. - person pithyless; 17.03.2010
comment
Я не уверен, насколько это возможно для вас, но то, что я сделал со своим приложением, заключалось в том, что я закрывал его каждый раз, когда пользователь переходил на другой экран (нажимал кнопку «Отмена» или форма теряла фокус). Таким образом, он ВСЕГДА завершается и запускается заново. Это может вам помочь? - person Chris; 17.03.2010
comment
К сожалению, в моем случае это не подходит (фоновое отслеживание GPS и т. Д.). Но я просто продолжу копаться в коде; в надежде найти ошибку, которая вызывает проблемы с синхронизацией. :) - person pithyless; 17.03.2010
comment
Синхронизация приложений выполняется не в CE, а в оболочке WinMo. - person ctacke; 17.03.2010