2012-11-07 34 views
1

我創建一個BackgroundWorker的和它的DoWork函數內終止一個控制檯模式應用程序,我有以下代碼:如何從一個BackgroundWorker

 foreach (string newFilepath in newFilesPath) 
     { 
         if (!File.Exists(encryptedFilePath)) 
         { 
          encryptedFiles.Add(encryptedFilePath); 
          Helper.SendErrorMail(null, "Could not find encrypted file.", encryptedFilePath); 
          Application.Exit(); 
         } 
         else 
         { 
          Helper.Count_DataFeeds++; 
          File.Delete(newFilepath); 
         } 
     } 

按照這個代碼,我應該只看到一個郵件,因爲應用程序存在,但是我看到8封郵件(對於每個迭代的文件)。爲什麼應用程序不退出?我想立即殺死應用程序。

這是一個控制檯應用程序。

+0

也許這段代碼是在一個單獨的線程中執行的,並且發生異常。 – lstern

+0

是的BackgroundWorker正在執行的代碼中的代碼如上所示。 –

回答

0

Environment.Exit是需要的。

+0

這是不合邏輯的給它在 –

+0

@MicahArmantrout什麼?您的評論沒有任何意義。我問如何立即殺死應用程序和Environment.Exit做到這一點。 –

+0

如果您已經在問題中顯示該答案,您如何給出答案。這沒有任何解釋 –

1

您需要從對消息泵的基本瞭解開始。什麼是UI線程,在某些非常低的水平,是一個while循環:

while(!shouldQuitapplication) 
{ 
    Item nextItem = queue.GetNextItem(); 
    nextItem.Run(); 
} 

每次調用Control.Invoke你添加一個新的項目排隊時間,每次鉤觸發一個事件(鼠標移動,按鈕點擊等),它會向隊列中添加一個新項目。所有這些項目都是按照收到的順序同步進行的。

Application.Exit本質上是一旦隊列中的所有現有項目都完成後結束整個過程的一種方法。

因爲你有一個BackgroundWorker運行,除了UI線程正在做的事情之外,它還在做「其他的東西」。當您告訴UI線程退出時,將需要一些時間來完成隊列中剩餘的任務。 (這就是爲什麼你看到後臺任務執行一些更多的操作;這個數字可能會有所不同。)

請注意,只要沒有更多的非後臺線程,整個進程就會被拆除。 UI線程是非後臺線程,而您使用的BackgroundWorker使用後臺線程。當UI線程結束時,後臺工作人員將被停止。如果您手動創建非UI線程,那麼它可能會使進程保持「啓動」狀態,即使在UI線程停止後它也不會停止。 (這將是一個倒退,但很明顯,這在這種情況下沒有幫助。)

正如另一個答案中提到的,解決方案是確保後臺任務在您撥打Application.Exit要麼調用breakreturn,要麼只是以不同的方式構造循環,以便停止在無效項目上。

2

這是一個控制檯應用程序

這意味着Application.Exit()將沒有任何效果,它僅關閉打開的Winform形式。由於關閉主表單的副作用會導致消息循環退出。其中完成了Application.Run()調用,它完成了Main()方法並終止了該應用程序。

控制檯模式應用程序沒有任何窗口也沒有消息循環。你應該使用Environment.Exit()來代替。

相關問題