Background Worker 被调用两次
Background Worker is called twice
我的后台工作程序有问题,它被调用了两次,从而增加了我的长例程的执行时间,我手动创建了后台工作程序,所以没有机会在 initializeComponent( ) 方法,我们将不胜感激。
这是我的代码:
// constructor
public TeacherScheduleForm(Therapist therapist)
{
this.therapist = therapist;
InitializeComponent();
bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
load = new LoadingForm();
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
load.AppendProgress(e.ProgressPercentage);
// load.AppendText(e.ProgressPercentage.ToString() + "%");
Console.Write("Progress: " + e.ProgressPercentage);
// MessageBox.Show("Progress : " + e.ProgressPercentage);
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
MessageBox.Show("Cancelled");
}
else if (!(e.Error == null))
{
MessageBox.Show("Error : " + e.Error);
}
else
{
updateUI();
load.Close();
Console.Write( "Done!");
}
}
// do work of background worker
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; (i <= 2); i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
Console.Write("Before Doing work");
setup(therapist.therapistID + "", schoolYear);// the time consuming operation
Console.Write("Doing work");
//System.Threading.Thread.Sleep(100);
worker.ReportProgress((i*5));
}
}
}
当用户通过以下代码中的组合框选择学年时调用后台工作程序:
private void comboBoxSchoolYear_SelectedIndexChanged(object sender, EventArgs e)
{
//load = new LoadingForm();
schoolYear = int.Parse(comboBoxSchoolYear.SelectedValue + "");
try{
if (!bw.IsBusy)
{
bw.RunWorkerAsync();
load.ShowDialog();
}
else
{
bw.CancelAsync();
}
}
catch(Exception ex)
{
Console.Write("Error : " + ex.Message);
}
}
您正在创建事件处理程序后加载表单。那是我唯一能想到的麻烦。尝试先加载表单,然后创建处理程序。
原因: 在 InitializeComponent();
时 IndexChanged
通常会启动,因为控件在此时设置了它的索引。直到现在我还没有注意到 FormLoad 上的这种行为。但是我在这里看不到任何其他问题,值得一试。
IF 这并不能解决问题,如果 TeacherScheduleForm
被调用两次,您还应该注意。
方便调试的东西:
MessageBox.Show((new StackTrace().GetFrame(0).GetMethod().Name));
将其粘贴到您的 event/method 或其他任何地方。它将弹出一个消息框,其中包含调用您当前方法的方法名称。在这种情况下(来自评论)它会提出 2 个消息框,对两者都说 TeacherScheduleForm
。
我已将其保存到我的代码片段中。
我的后台工作程序有问题,它被调用了两次,从而增加了我的长例程的执行时间,我手动创建了后台工作程序,所以没有机会在 initializeComponent( ) 方法,我们将不胜感激。
这是我的代码:
// constructor
public TeacherScheduleForm(Therapist therapist)
{
this.therapist = therapist;
InitializeComponent();
bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
load = new LoadingForm();
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
load.AppendProgress(e.ProgressPercentage);
// load.AppendText(e.ProgressPercentage.ToString() + "%");
Console.Write("Progress: " + e.ProgressPercentage);
// MessageBox.Show("Progress : " + e.ProgressPercentage);
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
MessageBox.Show("Cancelled");
}
else if (!(e.Error == null))
{
MessageBox.Show("Error : " + e.Error);
}
else
{
updateUI();
load.Close();
Console.Write( "Done!");
}
}
// do work of background worker
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; (i <= 2); i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
Console.Write("Before Doing work");
setup(therapist.therapistID + "", schoolYear);// the time consuming operation
Console.Write("Doing work");
//System.Threading.Thread.Sleep(100);
worker.ReportProgress((i*5));
}
}
}
当用户通过以下代码中的组合框选择学年时调用后台工作程序:
private void comboBoxSchoolYear_SelectedIndexChanged(object sender, EventArgs e)
{
//load = new LoadingForm();
schoolYear = int.Parse(comboBoxSchoolYear.SelectedValue + "");
try{
if (!bw.IsBusy)
{
bw.RunWorkerAsync();
load.ShowDialog();
}
else
{
bw.CancelAsync();
}
}
catch(Exception ex)
{
Console.Write("Error : " + ex.Message);
}
}
您正在创建事件处理程序后加载表单。那是我唯一能想到的麻烦。尝试先加载表单,然后创建处理程序。
原因: 在 InitializeComponent();
时 IndexChanged
通常会启动,因为控件在此时设置了它的索引。直到现在我还没有注意到 FormLoad 上的这种行为。但是我在这里看不到任何其他问题,值得一试。
IF 这并不能解决问题,如果 TeacherScheduleForm
被调用两次,您还应该注意。
方便调试的东西:
MessageBox.Show((new StackTrace().GetFrame(0).GetMethod().Name));
将其粘贴到您的 event/method 或其他任何地方。它将弹出一个消息框,其中包含调用您当前方法的方法名称。在这种情况下(来自评论)它会提出 2 个消息框,对两者都说 TeacherScheduleForm
。
我已将其保存到我的代码片段中。