2012-05-20 70 views
-2

這一個讓我難住。我有一個簡單的實用工具,可以幫助企業安裝軟件。單組分備份應用程序數據文件的用戶目前擁有自己的計算機上,並將它們保存到桌面上的文件夾:C#BackgroundWorker_DoWork只做一些工作

private void backupButton_Click(object sender, EventArgs e) 
{ 
    backgroundBackup.RunWorkerAsync(); 
} 


private void backgroundBackup_DoWork(object sender, DoWorkEventArgs e) 
{ 
    ... 
} 

private static void CopyAll(DirectoryInfo source, DirectoryInfo target) 
{ 
    ... 
} 

// I removed the message boxes from DoWork, and added a RunWorkerCompleted event, 
// but neither the confirmation nor the error messgae box from RunWorkerCompleted are shown. 

private void backgroundBackup_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    ... 
} 

這工作,但不會產生預期的結果。我把這個操作放在後臺線程上,因爲每個用戶備份的文件總大小可能接近1或2個。每次運行時,目標中的一些(但不是全部)文件和文件夾將被複制到目標,並且每次都複製所複製的文件夾。有時候只有很少的文件和文件夾被複制,有時幾乎所有的東西都被複制,但從來不是整個目標。如果將此操作放置在簡單的控制檯應用程序中,則它每次都有效。有什麼我需要了解的BackgroundWorker類,導致它不執行DoWork方法中的所有工作?

編輯:

我想我可能是在此問題上與BackgroundWorker的類複雜。我跟一個同事,和他們建議創建一個新線程的一種簡單的方法來處理潛在的漫長的過程:

private void backupButton_Click(object sender, EventArgs e) 
    { 
     Thread backupThread = new Thread(backupThreadJob); 
     backupThread.Start();  
    } 

    private void backupThreadJob() 
    { 
     try 
     { 
      //copy files and stuff 
     } 

     catch(Exception ex) 
     { 
      MessageBox.Show("Error: " + ex.Message); 
     } 
    } 

這得到對我所做的工作;我嘗試使用BackgroundWorker時沒有成功,並且始終無法弄清爲什麼只有一些文件被複制。感謝大家的幫助!

+0

我猜想一些異常正在提出,但是你的消息框不顯示,因爲你是從後臺線程調用而不是主UI線程。您可能應該在UI線程上調用這些方法。 –

+1

我期望你有一個異常,並且消息框沒有顯示,因爲它不是UI線程。嘗試記錄異常,而且通常不會消耗所有異常。它使調試噩夢,因爲你現在可能已經意識到 –

+0

你有沒有看過你的catch塊中的MessageBox?嘗試在後臺線程中拋出一個硬編碼的異常來查看是否顯示消息框。我的猜測是你的過程拋出錯誤。 –

回答

4

這不是一個完整的答案。但我能想象,下面有事情做的問題:

記住BackgroundWorker執行你DoWork方法的另一個非UI線程,所以它不是一個好主意,打電話MessageBox.Show那裏。您應該只做UI的東西,如果你是在UI(「前景」)正在運行的線程:

你一定要小心,不要操縱你的DoWork的事件處理程序的任何用戶界面對象。而是通過ProgressChanged和RunWorkerCompleted事件與用戶界面進行通信。MSDN reference page for the BackgroundWorker class

我可以想像的是,如果你的方法某處發生異常,並要顯示在catch塊一個消息框,這個調用觸發另一個異常,它沒有得到處理。 ..因此你的方法過早地中止。

+0

感謝您的回覆。我從DoWork中刪除了消息框,並添加了一個RunWorkerCompleted事件,但未顯示RunWorkerCompleted的確認和錯誤信息框。 –

+0

從您鏈接到的MSDN參考表中的第一個示例代碼中,我錯誤地認爲RunWorkerCompleted在DoWork完成時自動調用? –

+0

我的錯誤,長時間讀者,第一次海報... –

1

下面是一個示例,顯示您可以從背面的線程調用消息框。 MessageBox.Show是一個靜態方法調用,可以從後臺線程調用。你永遠不應該嘗試訪問你的UI層上的任何東西(包括綁定的支持對象 - 這裏認爲是WPF)。

這是一個用於消息框的例子。

我想複製10個文件,我在後臺開始複製過程。發生錯誤(存在文件等),並且您要提示用戶覆蓋 - 您可以顯示一個消息框,請求用戶確認。

private void button1_Click(object sender, EventArgs e) 
{ 
    BackgroundWorker bw = new BackgroundWorker(); 
    bw.RunWorkerCompleted += BwOnRunWorkerCompleted; 
    bw.DoWork += BwOnDoWork; 
    bw.RunWorkerAsync(); 
} 

private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs) 
{ 
    MessageBox.Show("This is a message from a background thread"); 
} 

private void BwOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs) 
{ 
    MessageBox.Show("Your done"); 
}