我对背景工作者有一点问题。我有两节课,我想同时工作。
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工作并给出结果。我该如何解决这个问题? 请给我一个关于这个问题的例子或修复我的代码。 谢谢你的帮助。
答案 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”可能不是你想要的,但是显示你的原则现在应该能够在两个人完成时看到两个答案。