2011-12-05 61 views
0

我在一個窗體下面使用背景工作,當我點擊一個按鈕時,它應該生成一個文檔,但GUI掛起,我不知道它爲什麼這樣做,因爲我感覺即時通訊使用背景工作權..有人可以幫助嗎?背景工作者,GUI的問題被絞死

private void btn_GenerateRevDoc_Click(object sender, EventArgs e) 
    { 
     DOC_GenerateVersDocBackgroundWorker = new BackgroundWorker(); 
     DOC_GenerateVersDocBackgroundWorker.WorkerReportsProgress = true; 
     DOC_GenerateVersDocBackgroundWorker.WorkerSupportsCancellation = true; 

     DOC_GenerateVersDocBackgroundWorker.DoWork += new DoWorkEventHandler(DOC_GenerateVersDocBackgroundWorker_DoWork); 
     DOC_GenerateVersDocBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(DOC_GenerateVersDocBackgroundWorker_ProgressChanged); 
     DOC_GenerateVersDocBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DOC_GenerateVersDocBackgroundWorker_RunWorkerCompleted); 
     System.Threading.Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; 
     if (Db.docVersionHistory != null && Db.docVersionHistory.Count > 0) 
     { 
      SaveFileDialog sfd = new SaveFileDialog(); 
      sfd.Title = "Export Review To"; 
      sfd.Filter = "Word files (*.doc)|*.doc|All files (*.*)|*.*"; 
      sfd.FilterIndex = 1; 
      sfd.FileName = ""; 

      if (sfd.ShowDialog() == DialogResult.OK) 
      { 


       if (!DOC_GenerateVersDocBackgroundWorker.IsBusy) 
        DOC_GenerateVersDocBackgroundWorker.RunWorkerAsync(sfd.FileName); 
      } 
     } 
     else 
     { 
      MessageBox.Show("No Review Records were found!"); 
     } 

    } 
    void DOC_GenerateVersDocBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     if (this.InvokeRequired) 
     { 
      Invoke(new MethodInvoker(delegate 
        { 

         DocumentsNavigator.GenerateWordRevisionHistoryDoc(DOC_GenerateVersDocBackgroundWorker, versionsList, Db, (string)(e.Argument)); 

        })); 
     } 
     else 
     { 
      DocumentsNavigator.GenerateWordRevisionHistoryDoc(DOC_GenerateVersDocBackgroundWorker, versionsList, Db, (string)(e.Argument)); 

     } 
    } 
+1

如果(! DOC_GenerateVersDocBackgroundWorker.IsBusy)如要創建一個新的BackgroundWorker每次按鈕被點擊 –

+0

你有C#-4.0和C#-3.0沒有意義。這真的有必要嗎? C#標籤不夠嗎? – DonkeyMaster

回答

1

您不完全瞭解BackgroundWorker應該如何使用以及Invoke方法的作用。

Invoke方法導致代碼在UI線程上被調用。所以,不要通過Invoke來傳遞DocumentsNavigator.GenerateWordRevisionHistoryDoc方法。 RunWorkerAsync很好。我不知道versionsListDb是什麼類型,但如果它們是UI對象,則可能需要將需要的值複製到新變量中。例如,如果versionsListListBox,則應該將所選值複製到新的string[],並將該string[]用作方法的參數。

這裏就是你認爲你想做的事:

  • 創建新的後臺工作

  • 初始化後臺工作

  • 禁用btn_GenerateRevDoc按鈕

  • 顯示SaveFileDialog

  • 啓動的BackgroundWorker(RunWorkerAsync

  • ProgressChanged事件,如果你顯示進度條或 東西,你可以更新,這個時候你確實有過時它 通過Invoke方法。

  • 而且在RunWorkerCompleted事件,顯示一個消息框或東西, 並再次啓用btn_GenerateRevDoc按鈕

哦,這條線應該完全被刪除:

System.Threading.Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; 
0

內,您的後臺工作,你再次轉發所有的工作,UI線程,這就是爲什麼你的UI是掛

if (this.InvokeRequired) 
     { 
      //this executes the work on UI thread 
      Invoke(new MethodInvoker(delegate 
        { 

         DocumentsNavigator.GenerateWordRevisionHistoryDoc(DOC_GenerateVersDocBackgroundWorker, versionsList, Db, (string)(e.Argument)); 

        })); 
     } 
     else 
     { 
//it will also be executed on UI thread  
    DocumentsNavigator.GenerateWordRevisionHistoryDoc(DOC_GenerateVersDocBackgroundWorker, versionsList, Db, (string)(e.Argument)); 

     } 
    } 
+0

但它是不同的用戶界面,這是另一個,如果我明白了 – Yasser

+0

只有一個UI線程,所以它會是相同的UI –

0

當我點擊一個按鈕,它應該產生一個文件,但是GUI掛起

從您的代碼我可以看到您應該輸入文件名並單擊確定。是否有保存對話框在某處打開?

嘗試編寫相同的代碼而不使用後臺工作。它仍然掛起?此外,觀察到條件if (!DOC_GenerateVersDocBackgroundWorker.IsBusy)沒有意義,因爲您每次創建新的後臺工作按鈕時都會點擊按鈕

-1

您正在做一些不安全的事情。而不是調用的

嘗試

if (this.InvokeRequired)   
{    this.BeginInvoke(new MethodInvoker(delegate      
    { 
+0

調用全部是問題 – DonkeyMaster

+0

這不是我的意思是關於調用,我只是建議爲了讓你的代碼更加清晰,你在非UI線程中調用了這個問題,調用generatewordrevistionHistory。你可能喜歡設置標誌並檢查標誌,祝你好運 – user182630

+0

你說得對。作爲一般規則,獨立於此問題,調用BeginInvoke比調用Invoke更安全。我沒有注意到MethodInvoker。 – DonkeyMaster

0

的問題是,你正在運行掛起GUI的工作線程的代碼,但你這樣做在Invoke方法。

Invoke方法在GUI的線程中運行代碼,因此掛起。

如果您絕對必須在GUI線程中調用DocumentsNavigator.GenerateWordRevisionHistoryDoc我不明白如何在不掛起GUI的情況下進行此調用。

嘗試重新考慮您的代碼,以便您不必在Invoke方法中的BackgroungWorker中運行任何代碼。