2012-09-20 78 views
0

下面是我的編碼:C#BackgroundWorker的繼續運行DoWork的

Form2 msgForm; 
    private void button3_Click_1(object sender, EventArgs e) 
    { 

     bw.WorkerReportsProgress = true; 
     bw.WorkerSupportsCancellation = true; 
     bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
     bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 

     msgForm = new Form2(); 

     try 
     { 
      bw.RunWorkerAsync(); 

      msgForm.ShowDialog(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 

    void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     // Coding that transmit protocol and will last around 2 minutes. 
    } 

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     msgForm.Close(); 
    } 

我用的是後臺工作方法,每次我點擊一個按鈕以發射持續約2分鐘協議。在傳輸過程中,From2將顯示「Please wait」。

但我使用這種編碼有一些問題。問題是,當我第一次點擊按鈕時,它會傳輸協議一次。之後,我再次點擊這是第二次,它傳輸協議兩次。之後,我再次點擊這是第三次,它傳輸協議3次....等等。每次點擊按鈕,傳輸協議的次數都會增加。

是不是說它只會運行一次無效的編碼bw_DoWork每次我點擊按鈕?

我的編碼有問題嗎?

回答

6

要追加每次點擊時間額外處理程序,然後它的運行與你之前添加的一切,它保持它(因爲對象仍然存在,你在那裏沿着再利用它)。

爲了解決這個問題,你需要:

  • 移動的方法中後臺工作人員的聲明(所以它的新的每一次,只有一個DoWork處理

就像這樣:

private void button3_Click_1(object sender, EventArgs e) 
{ 
    BackgroundWorker bw = new BackgroundWorker(); 
    // rest of your code 
} 
  • 移動該追加小時.DoWork += ...安德勒在類的構造函數

它主要取決於如果您在其他地方使用該工作。

+0

沒有亞歷克斯。我只是使用工作人員傳輸協議而已。 – Coolguy

+0

然後在方法中聲明它。 – Alex

+0

亞歷克斯,你是指通過移動方法內的後臺工作者的聲明是什麼意思? – Coolguy

0

它看起來像一個新的工人開始每一次點擊。 爲避免這種情況,請在再次啓動之前檢查工作人員是否忙碌。

try 
{ 
    if (!bw.IsBusy) 
     bw.RunWorkerAsync(); 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
} 

雖然BackgroundWorker的,它的工作,通過button3.Enabled = false;,您可以禁用按鈕重新啓用它在bw_RunWorkerCompleted方法,讓用戶明白,他必須等待,直到該過程完成後無法再次點擊。

+1

沒有。他每次都追加另一個處理程序。 – Alex

+0

@Alex我仔細檢查了這個問題,你說得對,我錯過了這一點。 upvoted你的答案。無論如何,我認爲檢查BackgroundWorker是否已在運行並相應地啓用/禁用按鈕是一個好主意=) –

0

首先確保您的列表/集合在傳輸代碼之前已清除。 然後在您的源代碼中使用BreakPoint,並記住您的BackgroundWorker無法運行兩次或更多,因爲您使用ShowDialog。

0

檢查工人忙:

if (!bw.IsBusy)   
    bw.RunWorkerAsync(); 

我還要禁用按鈕並更改文本如「運行」,而進程正在excecuted。

使用bw_RunWorkerCompleted方法事件調用,然後重新啓用按鈕並更改文本。此方法與UI在相同的線程上運行,因此不存在交叉線程問題。

在您的設計上,爲什麼您會顯示另一個表單以顯示「請稍等」通知?我建議你現有的形式更新的標籤或者異步過程開始之前(所以不能跨線程UI的問題),或者如果你需要後更新,那麼你可以使用以下命令:

lblNotify.Invoke(new Action(() => lblNotify.Text = @"Please wait")); 

上述隨後將允許你在主線程上運行你的請求。