2010-03-17 62 views
0

我已經繼承了一些我一直在更新的Windows移動代碼。我遇到了一個奇怪的錯誤,我希望即使有點模糊,也許它會觸發某人的記憶:由任務管理器關閉後,Windows移動應用程序將不會運行

運行應用程序(基本上是一個帶有P/Invoke gps代碼的榮耀的Forms應用程序),我切換到任務管理器,並通過結束任務關閉應用程序。似乎退出罰款(沒有錯誤,並從任務管理器中消失)。不幸的是,該應用程序拒絕再次啓動,直到我重新啓動手機或重新安裝CAB。

更糟的是:這個bug在HTC Diamond上是可重現的,但在HTC HD2上工作正常(即可以在EndTask之後再次運行)。

我能想到的唯一事情就是Dispose()和任務管理器之間的某種時間競爭。有任何想法嗎?

我也想到一個解決方法 - 我有一個工作「退出應用程序」例程,正確清理應用程序;我可以捕捉C#代碼中的EndTask事件來完成正確的清理嗎?

也許我只是缺少痛點...所有的想法表示歡迎:)

回答

4

當您使用任務管理器來關閉它,會發生以下情況:

  1. 的應用物(S)是發送WM_CLOSE消息
  2. 如果一段時間後的時候,他們仍在運行TerminateProcess使用。

如果您有一個不能退出的工作線程運行,進程通常不會完全終止。這在CF 1.0中很常見,其中線程的IsBackground屬性不存在。

由於TaskManager只枚舉表單標題,如果表單全部關閉,即使通過進程運行,它也不會顯示應用程序。當你嘗試再次執行時,shell會檢測到它已經在運行,並且簡單地切換到正在運行的(沒有UI)進程,所以看起來沒有任何事情發生。

您可以使用Remote Process Viewer驗證此行爲。

解決方法是修復您的工作線程代碼以正確退出。通常我使用布爾值或WaitHandle來表示它們應該退出。對於創建的所有線程,也應該設置IsBackground爲true。

+0

謝謝,這使我走上了正軌。我認爲我解決了線程問題..但在類似的問題上:如果我的主窗體產生一個ShowDialog(),我們在這一點通過TaskManager關閉應用程序;我們調用子窗體上的Closing事件。現在,如果我不告訴孩子關閉應用程序的其餘部分,我會回到原來的錯誤。另一方面,運行Aplication.Exit()意味着應用程序將始終退出(即使我想要做的就是關閉子窗體)。這兩個解決方案對我來說似乎都很愚蠢 - 我的孩子表單如何知道Close事件來自TaskManager或點擊右上角的「OK」 – pithyless 2010-03-17 14:56:49

+0

顯然現在我的治療比疾病(對於兒童形式)更加致命。而且,這是HTC Diamond的問題;宏達HD2的作品很好。我不知道該如何解決這個問題。 – pithyless 2010-03-17 14:57:53

0

我不知道你到底是什麼問題,但我覺得WinCE的設備往往只允許一個應用程序的一個實例立即運行。這可能意味着TaskManager沒有正確地清理應用程序,所以它認爲它仍然在運行,並且不會啓動另一個副本,或者它可能實際上仍在運行。

嘗試在應用程序中放入一些代碼,檢測它是否已在運行。 另外,請仔細檢查你是否正確地清理了所有東西,尤其是線程等,因爲關閉應用程序的時間可能與你手動執行的時間不同。

希望任何的幫助

+0

感謝克里斯的迴應。據我所知,這確實是一個問題:WinCE只允許一個實例。所以問題是TaskManager以不同的方式清理應用程序,並且我處於Catch-22中。由於該程序從未真正「退出」,因此我無法再次啓動它(因此無法檢查它是否已在運行)。該應用程序也不知道它被請求退出,除非我能以某種方式捕獲TaskManager終止請求。我會仔細檢查線程清理,但我希望應用程序能夠找到有關TaskManager終止請求的方法;否則,該應用程序是在黑暗中。 – pithyless 2010-03-17 12:18:55

+0

我不知道這對你是否可行,但我對我的應用程序做了什麼就是關閉它,每次用戶去到另一個屏幕(按下取消,或表單失去焦點)。這樣它總是退出並開始新鮮。這可以幫助你嗎? – Chris 2010-03-17 12:29:54

+0

不幸的是,這是我的情況(禁止背景GPS跟蹤等)。但我會繼續深入研究代碼;希望找到導致計時問題的「哎呀」。 :) – pithyless 2010-03-17 12:39:20

1

自從您的問題出現一年後,這可能就是答案。

我有同樣的問題。我的應用程序有MinimizeBox = False,這將在窗體的右上角顯示一個小的Ok,並且是處理關閉事件的唯一方法(Cross with MinimizeBox = True不會引發ClosingEvent)。在這個事件中,我取消了關閉並執行了一些自定義代碼,並最小化了表單,使其看起來像標準的「交叉關閉事件」行爲。

問題是,在HTC鑽石上,當你殺了一個任務,它引發了同樣的關閉事件,我的代碼再次取消它。奇怪的是,在任務管理器中,應用程序已經消失,但是如果啓動原始的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); 
    } 
} 
相關問題