簡體   English   中英

將不同的方法/功能傳遞給后台工作者的DoWork事件

[英]Pass different method/function to DoWork event of Background worker

請不要理解我對這個問題以及我用過的術語的無知。 請糾正我錯誤的地方。

我已經使用工具箱中的后台工作者到我的表單上,並且我將一個方法傳遞給DoWork事件。 我在背景工作者的第一次嘗試中理解的是,我可以使用我僅為1個任務創建的后台工作程序。 見下面的代碼:

private void btn1_Click(object sender, EventArgs e)
{
   // Should call the uploadToDB1 using BackgroundWorker's DoWork event.
     backgroundWorker1.RunWorkerAsync();
}

private void btn2_Click(object sender, EventArgs e)
{
    // Should call the uploadToDB2 using BackgroundWorker's DoWork event.
    backgroundWorker1.RunWorkerAsync();
}

private void uploadToDB1()
{
    // Code for uploading to DB 1.
}        

private void uploadToDB2()
{
    // Code for uploading to DB 2.
}  

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {

        uploadToDB1(); // I want to change this to uploadToDB2 i.e. a variable method, How do I assign a call to this?

    }
    catch (Exception ex)
    {

        MessageBox.Show(ex.Message);
    }

}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Visible = true;
    progressBar1.Maximum = maxRecords;
    lblProgress.Text = Convert.ToString(e.ProgressPercentage.ToString() + "/" + maxRecords);
    progressBar1.Value = e.ProgressPercentage;

}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    progressBar1.Visible = false;
    lblProgress.Text = "";
}

我需要能夠動態地將方法傳遞給DoWork事件,而不需要創建多個后台Worker,因為與后台Worker相關的其他事件中的操作保持不變。

你能告訴我該如何做到這一點嗎?

使用TPL更新了代碼,但是我遇到了跨線程錯誤。 你能幫忙修改一下代碼嗎? 只有在上傳到DB 1完成后才能上傳到DB 2。 因此,每次上傳時都需要更新標簽和進度條。 我還需要將不同的文本傳遞給標簽。

private void btn1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(uploadToDB1);
}
private void uploadToDB1()
{
    for(i=0;i<dt.rows.count-1;i++)
    {
        // Code for inserting into DB1.

        progressbar1.maximum=dt.rows.count-1;
        progressbar1.value=i;
    }
    uploadToDB2();

}

private void uploadToDB2()
{
    for(i=0;i<dt.rows.count-1;i++)
    {
        // Code for inserting into DB2.

        progressbar1.maximum=dt.rows.count-1;
        progressbar1.value=i;
    }

}

可以做什么,而且有點像黑客,是將Action作為調用DoWorkAsync的參數DoWorkAsync

var bw = new BackgroundWorker();
bw.DoWork += (s, o) => 
{
    Action actualWork = (Action)o.Argument;
    actualWork();
}

當您調用DoWorkAsync

Action action = () => DoSomething();
bw.RunWorkerAsync(action);

相反,正如@Sriram建議的那樣,查看Task Parallel Library ,它將使您的生活更輕松:

private async void btn1_Click(object sender, EventArgs e)
{
    await Task.Run(UpdateFirst);
    // Update UI here.
}

private async void btn2_Click(object sender, EventArgs e)
{
    await Task.Run(UpdateSecond);
    // Update UI again.
}

關於TPL的廣泛答案和IProgess<T>可以在如何在異步方法中向UI提供反饋中找到

暫無
暫無

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

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