2011-04-15 76 views
4

在傳統的應用程序中,我們有一個單一的winform,在執行單擊按鈕時執行代碼時鎖定...以及在代碼執行之前它不鎖定它只是「停止響應」。簡單的加載形式/線程

什麼是最好的(最少量的代碼和工作)方式將下面的代碼包裝到一個單獨的線程,並顯示一個加載窗口(frmLoading),而它執行?我知道這應該是相對簡單的,但我已經嘗試了一些尚未完全解決的問題。

private void btnSynch_Click(object sender, EventArgs e) 
{ 
    btnSynch.Enabled = false; 

    if(chkDBSynch.Checked) 
     PerformDBSyncronization(); 

    if(chkAppSynch.Checked) 
     PerformApplicationSyncronization(); 

    btnSynch.Enabled = true; 
} 

編輯: 好吧,我應該提到曾試圖BackgroundWorker的,但我想通了,我在那裏絆倒了....這段代碼執行和加載形式得到拋出的主要形式背後這就是爲什麼我認爲它不起作用。任何人都可以告訴我如何防止這種情況發生?

private void btnSynch_Click(object sender, EventArgs e) 
    { 

     btnSynch.Enabled = false; 
     frmLoading loadingWindow = new frmLoading(); 
     loadingWindow.Show(); 

     BackgroundWorker bw = new BackgroundWorker(); 
     bw.DoWork += (s, args) => 
     { 

      Thread.Sleep(6000); //TODO:just for testing 
      if(chkDBSynch.Checked) 
      PerformDBSyncronization(); 

      if(chkAppSynch.Checked) 
      PerformApplicationSyncronization(); 
     }; 
     bw.RunWorkerCompleted += (s, args) => 
     { 
      loadingWindow.Close(); 
     }; 
     bw.RunWorkerAsync(); 

     btnSynch.Enabled = true; 
    } 
+0

你需要知道什麼時候做,或者這是一種「發射後不管」的情況? – richard 2011-04-15 20:47:07

+0

@Richard DesLonde - 我不需要知道它什麼時候完成,只需要給用戶一個表明表單沒有「凍結」的指示。 – AGoodDisplayName 2011-04-15 20:50:34

回答

2

我覺得很傻......加載表單彈出後面的主窗體,這就是爲什麼我認爲它不是開放。我將TopMost屬性設置爲true,一切按預期工作。

編輯:
這是一個很好的解釋,爲什麼我的窗體彈出窗口後面,我只是不期待打開窗口的線程不使用主窗體作爲所有者。

Why use a owner window in MessageBox.Show?

我結束了我的代碼看起來像

 frmLoading loadingWindow = new frmLoading(); 
     loadingWindow.Show(this); 

     BackgroundWorker bw = new BackgroundWorker(); 
     bw.DoWork += (s, args) => 
     { 
      this.Invoke(new MethodInvoker(() => this.Enabled = false)); 

      if(chkDBSynch.Checked) 
      PerformDBSyncronization(); 

      if(chkAppSynch.Checked) 
      PerformApplicationSyncronization(); 
     }; 
     bw.RunWorkerCompleted += (s, args) => 
     { 
      loadingWindow.Close(); 
      this.Invoke(new MethodInvoker(() => this.Enabled = true)); 

     }; 

     bw.RunWorkerAsync(); 
+1

將加載表單的所有者設置爲主窗體:'loadingForm.ShowDialog(this)'。 – Tergiver 2011-04-15 22:04:06

+0

@Tergiver - 謝謝,這實際上是我最終做的,但是我沒有使用ShowDialog,因爲主表單會等待結果。 (我只是將最頂層的屬性設置爲快速測試)......我會更新我的答案。 – AGoodDisplayName 2011-04-18 15:55:41

+0

使用ShowDialog可防止用戶與所有者窗口交互,它不會「等待結果」。用戶界面線程仍然會抽取消息,所有者窗口仍然「活着」。如果使用Show,用戶可以與主窗口進行交互,導致加載表單消失,並激活可能未啓動的控件。 – Tergiver 2011-04-18 20:37:22

0

爲此目的使用BackgroundWorker

+0

我試過backgroundworker,但我做錯了什麼。加載形式永遠不會彈出....我有點希望有人有一些代碼示例。 – AGoodDisplayName 2011-04-15 20:51:17

+0

[此](http://www.dotnetperls.com/backgroundworker)是一個非常友好的介紹。如果您有權訪問此書[C#2008 Express Edition:立即構建程序](http://www.microsoft.com/learning/en/us/book.aspx?ID=12281&locale=en-us),它具有很好的例子。 – jonsca 2011-04-15 21:07:55