簡體   English   中英

C#Backgroundworker繼續運行DoWork

[英]C# Backgroundworker keep on running 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將顯示“請稍候”。

但是我在使用這種編碼時遇到了一些問題。 問題是,當我第一次單擊該按鈕時,它將傳輸一次協議。 之后,我再次單擊第二次,它兩次傳輸協議。 之后,我再次單擊第三次,它發送了3次協議。...依此類推。 每次單擊按鈕,傳輸協議的次數都會增加。

每次單擊按鈕時,它只會在void bw_DoWork中的編碼一次后運行嗎?

我的編碼有問題嗎?

每次單擊時,您都將附加一個附加處理程序,然后該處理程序將與之前添加的所有內容一起運行,並保持原樣(因為該對象仍在此處,因此您將重新使用它)。

要解決此問題,您需要執行以下任一操作:

  • 將后台工作程序的聲明移動到方法內(因此每次都是新的,只有一個DoWork處理程序

像這樣:

private void button3_Click_1(object sender, EventArgs e)
{
    BackgroundWorker bw = new BackgroundWorker();
    // rest of your code
}
  • 移動.DoWork += ... ,它將處理程序追加到類的構造函數中

這主要取決於您是否在其他地方使用了該工作人員。

每次點擊似乎都有一個新工作人員開始。 為避免此行為,請在再次啟動之前檢查工作人員是否忙碌。

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

並且您可以在backgroundworker進行工作時禁用該按鈕,方法是button3.Enabled = false; 並在bw_RunWorkerCompleted方法中重新啟用它,讓用戶理解他必須等待並且無法再次單擊,直到該過程完成。

首先,在傳輸代碼之前,請確保您的列表/收藏夾是清晰的。 然后在源代碼中使用BreakPoint,並記住您的BackgroundWorker不能運行兩次或多次,因為您使用ShowDialog。

檢查工作人員是否忙:

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

我還將禁用該按鈕,並在執行過程時將文本更改為“正在運行”。

使用bw_RunWorkerCompleted方法事件調用,然后重新啟用按鈕並更改文本。 此方法與UI在同一線程上運行,因此沒有跨線程問題。

在您的設計上,為什么要顯示另一張“請稍候”通知的表格? 我建議您在異步過程開始之前更新現有表單上的標簽(這樣就不會引起跨線程UI問題),或者如果您需要在之后進行更新,則可以使用以下命令:

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

然后,以上內容將允許您在主線程上運行請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM