2014-01-23 107 views
0

我正在開發一個簡單的winforms C#應用程序。我想使用後臺工作人員在頂層顯示加載表單,而另一個後臺工作人員正在向我的WCF服務器進行諮詢。背景工人懷疑

我的WinForms應用程序是這樣的: 我有一個MainForm和大量的UserControls。當我啓動應用程序時,我將一個LoginUserControl添加到MainForm控件。當我單擊LoginUserControl中的「登錄按鈕」時,我想同時顯示加載表單和諮詢服務器。稍後,我需要向加載後臺工作者發送一個信號,指示Server Consult Background Worker已完成。

我的問題是,我是否應該爲每個需要加載面板的用戶控件實現2個後臺工作?以及如何實施後臺工作人員之間的溝通?

+0

這可能有幫助 - 類似的東西(閃屏)http://stackoverflow.com/questions/7955663/how-to-build-splash-screen-in-windows-forms-application – owen79

+0

如果可能的話,使用' async'和'await'而不是'BackgroundWorker'處理I/O綁定操作。 –

+0

爲什麼兩個BackgroundWorker?顯示頂部表單,調用一個後臺工作器,並在最後完成的事件刪除表單。 – Paparazzi

回答

0

首先,從BackgroundWorker開始Form是一個壞主意。這會干擾Windows窗體所具有的單個UI線程。

您最好從UI線程打開Form,並從BackgroundWorker中調用Invoke來關閉表單。

form.Invoke((MethodInvoker)delegate() 
{ 
    busyForm.Close(); 
}); 
1

後來,我需要發送到加載後臺工作,指示該服務器請教後臺工作已完成的信號。

不,你不需要。

後臺工作人員正是這樣說:在後臺執行任務的「工作人員」。你的情況中的任務是與你擁有的WCF服務通信的方法。工作完成後(或拋出異常),工作人員將結束。所以,事件的順序如下:

  • 啓動工作(必須是第一,如果你的表格是模態)
  • 顯示形式
  • 傾聽工人RunWorkerCompleted事件隱藏窗體

事實上,我已經創建了一個類似這樣的表單,只有我沒有與服務器通信(實際上並不重要),並且我顯示了一個簡單的進度條。

public partial class FastForwardForm : Form 
{ 
    private Exception asyncError; 

    public event DoWorkEventHandler DoWork 
    { 
     add { worker.DoWork += value; } 
     remove { worker.DoWork -= value; } 
    } 

    public FastForwardForm() 
    { 
     InitializeComponent(); 
    } 

    public Exception AsyncError 
    { 
     get { return asyncError; } 
    } 

    private void FastForwardForm_Shown(object sender, EventArgs e) 
    { 
     worker.RunWorkerAsync(); 
    } 

    private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     progressBar.Value = e.ProgressPercentage; 
     statusLabel.Text = e.UserState.ToString(); 
    } 

    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (e.Error != null) asyncError = e.Error; 
     HideProgressForm(); 
     worker.Dispose(); 
    } 

    private void HideProgressForm() 
    { 
     //not actually needed, the callback runs on the UI thread. 
     if (InvokeRequired) 
     { 
      Invoke((Action)HideProgressForm); 
      return; 
     } 
     Close(); 
    } 
} 

請注意以下事項:

  • workerControl子類,所以我加了它通過形式編輯器。這也意味着它的回調是在UI線程上執行的,而你不需要需要我添加的if (InvokeRequired)部分。不要問我爲什麼在那裏,我在重構後錯過了:)
  • 表單爲你做了一些骯髒的工作:只要顯示它就啓動工作。存儲過程的例外。公開DoWork,以便您可以從表單外的任何位置添加背景作品。
  • 該代碼並不完美:如果您需要重新使用該表單,則必須刪除worker.Dispose();並將其添加到表單Dispose()方法中。

現在,如果您需要在表單中顯示一些「等待」動畫,則不需要其他工作人員。你需要一個Timer控件來刷新動畫,但這是另一回事。