如何同时工作2个背景工作者?

时间:2014-01-13 19:17:15

标签: c# .net

我对背景工作者有一点问题。我有两节课,我想同时工作。

private System.ComponentModel.BackgroundWorker bg1,bg2 ;

private void InitializeBackgroundWorker()
{
    bg1= new System.ComponentModel.BackgroundWorker();
    bg1.DoWork +=new System.ComponentModel.DoWorkEventHandler(bg1_DoWork);

    bg2 = new System.ComponentModel.BackgroundWorker();
    bg2.DoWork += new System.ComponentModel.DoWorkEventHandler(bg2_DoWork);
}

private void bg1_DoWork(object sender,System.ComponentModel.DoWorkEventArgs e)
{
    p myp = (p)e.Argument;
    myp.solver();
    quantities = myp.dizi_ata(myp.miktarlar);
    sonuc_listele(myp.miktarlar, myp.maliyet, myp.toplam_ceza,"P");
}

private void bg2_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    a mya = (a)e.Argument;
    mya.solver();
    quantities = mya.dizi_ata(mya.miktarlar);
    sonuc_listele(mya.miktarlar, mya.maliyet, mya.toplam_ceza, "ABC");
}

并且,我将这些背景工作者称为以下代码

try        
{
    InitializeBackgroundWorker();
    if (!bg1.IsBusy && !bg2.IsBusy)
    {
        bg1.RunWorkerAsync(myp);
        bg2.RunWorkerAsync(mya);
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

当我尝试这个代码时,bg2不工作(不给结果)但是bg1工作并给出结果。我该如何解决这个问题? 请给我一个关于这个问题的例子或修复我的代码。 谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

将每个工作人员的结果存储在单独的变量中,在这种情况下 quantity_bg1 quantity_bg1

private void bg1_DoWork(object sender,System.ComponentModel.DoWorkEventArgs e)
{
    p myp = (p)e.Argument;
    myp.solver();
    quantities_bg1 = myp.dizi_ata(myp.miktarlar);
    sonuc_listele(myp.miktarlar, myp.maliyet, myp.toplam_ceza,"P");
}

private void bg2_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    a mya = (a)e.Argument;
    mya.solver();
    quantities_bg2 = mya.dizi_ata(mya.miktarlar);
    sonuc_listele(mya.miktarlar, mya.maliyet, mya.toplam_ceza, "ABC");
}

此外,您可能会因为始终初始化工作人员而导致内存泄漏,即使您没有启动它们

try        
{
    if(bg1 == null)
    {
        InitializeBackgroundWorker();
    }

    if ((bg1 != null) && (!bg1.IsBusy))
    {
        bg1.RunWorkerAsync(myp);
    }

    if ((bg2 != null) && (!bg2.IsBusy))
    {
        bg2.RunWorkerAsync(mya);
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

答案 1 :(得分:1)

如果您的最终答案依赖于两个后台工作人员完成后的结果,则可能是最后一个完成的人,就您的数量字段获胜。我想你可能会接近你的任务,但可能会提供这种调整。创建两个字段以分别保存每个结果,并在完成两个进程结束时,然后通过连接到RunWorkerCompleted事件来执行任何其他操作。

// Add fields first...
int BG1_Qty;
int BG2_Qty;

// add flag fields to CONFIRM a step is done
bool BG1_Finished;
bool BG2_Finished;

private void InitializeBackgroundWorker()
{
    bg1= new System.ComponentModel.BackgroundWorker();
    bg1.DoWork += new System.ComponentModel.DoWorkEventHandler(bg1_DoWork);

    bg2 = new System.ComponentModel.BackgroundWorker();
    bg2.DoWork += new System.ComponentModel.DoWorkEventHandler(bg2_DoWork);

    // have BOTH background workers call same "I'm Finished" method when they are done
    bg1.RunWorkerCompleted += TasksFinished;
    bg2.RunWorkerCompleted += TasksFinished;

    // NOW Run them BOTH
    bg1.RunWorkerAsync();
    bg2.RunWorkerAsync();
}

private void bg1_DoWork(object sender,System.ComponentModel.DoWorkEventArgs e)
{
    p myp = (p)e.Argument;
    myp.solver();
    BG1_Qty = myp.dizi_ata(myp.miktarlar);
    sonuc_listele(myp.miktarlar, myp.maliyet, myp.toplam_ceza,"P");
    BG1_Finished = true;
}

private void bg2_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    a mya = (a)e.Argument;
    mya.solver();
    BG2_Qty = mya.dizi_ata(mya.miktarlar);
    sonuc_listele(mya.miktarlar, mya.maliyet, mya.toplam_ceza, "ABC");
    BG2_Finished = true;
}

private void TasksFinished(object sender, RunWorkerCompletedEventArgs e)
{
   // since BOTH background workers will call this method when they complete,
   // all we need to do is look at the flags... whoever wins first, it will not
   // do anything, but when the SECOND finishes, it will.
   if( BG1_Finished &&  BG2_Finished)
   {
      quantities = BG1_Qty + BG2_Qty;
   }
}

明显的结尾“TaskFinished”可能不是你想要的,但是显示你的原则现在应该能够在两个人完成时看到两个答案。