如何使用 backgroundworker 进程 c# 以另一种形式更改标签?
How do i change label in another form with backgroundworker process c#?
我的项目 c# 中有 2 个表单(formA 和 formB),我想 运行 当我在 formA 中单击一个按钮时在后台工作程序中进行一些处理。
我可以从 backgroundworker 更新到 formB 中的标签吗?
这是formA
中的代码
private void button1_Click_1(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Stimulus stimulus = new Stimulus();
Stopwatch watch = new Stopwatch();
stimulus.Show();
stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus("+"); });
watch.Start();
do
{
} while (watch.Elapsed.Seconds != 2);
watch.Restart();
stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus("MAJU"); });
do
{
} while (watch.Elapsed.Seconds != 6);
watch.Restart();
stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus(""); });
do
{
} while (watch.Elapsed.Seconds != 2);
watch.Stop();
stimulus.Close();
}
这里是 formB 中的代码
public Stimulus()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
}
public void perbaharuiStimulus(string stimulus)
{
this.Invoke((MethodInvoker)delegate
{
lbStimulus.Text = stimulus;
});
}
谢谢关注..
您可以使用 Invoke(...)
从后台工作人员以任何形式更新标签,就像您所做的那样。 (假设刺激是一个领域)。
调用一次 Invoke 就足够了。 Stimulus.Invoke
在刺激形式的控制线程上执行委托。因此,您可以决定何时分派线程。我建议在 perbarauiStimulus
中执行此操作,因为这会减少有人忘记发送呼叫的可能性。
但是您的代码存在一个潜在问题:
不要对经过的时间使用精确比较。更喜欢使用“>=”。由于您处理的是秒,这很少会成为实际问题,但它可能会导致无限循环。
如果 stimulus
不是一个字段,您必须在后台工作程序的 Stimulus
外部 创建一个实例,因为如果您在内部创建它worker 方法,表单将 运行 它的消息在后台工作线程上循环。这消除了后台工作者的使用,因为操作 运行s 现在从 sytimulus 视图同步。
您不应该在后台线程中创建表单。这样做会将表单分配给 that 线程而不是 UI 线程,这意味着表单现在与消息泵位于不同的线程上。
解决此问题的方法是在 UI 线程上调用表单的实例化和查看,然后您的后续 Invoke
调用应该可以工作。
Stimulus stimulus;
this.Invoke((MethodInvoker)delegate
{
stimulus = new Stimulus();
stimulus.Show();
});
//No need to invoke this since perbaharuiStimulus() calls Invoke() as well.
stimulus.perbaharuiStimulus("+");
//The rest of your code...
除此之外,您做的一切都正确。
您可以像下面这样更改您的代码,它会正常工作。
将 perbaharuiStimulus 代码更改为
lbStimulus.Text = stimulus;
将WorkerReportsProgress
改为True
将backgroundWorker1_DoWork
改为以下
Stimulus stimulus = new Stimulus();
Stopwatch watch = new Stopwatch();
backgroundWorker1.ReportProgress(1, stimulus);
watch.Start();
do
{
} while (watch.Elapsed.Seconds != 2);
watch.Restart();
backgroundWorker1.ReportProgress(2, stimulus);
do
{
} while (watch.Elapsed.Seconds != 6);
watch.Restart();
backgroundWorker1.ReportProgress(3, stimulus);
do
{
} while (watch.Elapsed.Seconds != 2);
watch.Stop();
stimulus.Invoke((MethodInvoker)delegate { stimulus.Close(); });
添加 backgroundWorker1_ProgressChanged
事件并在其中放入以下代码
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Stimulus stimulus = ( Stimulus)e.UserState;
if(e.ProgressPercentage==1)
stimulus.perbaharuiStimulus("+");
if (e.ProgressPercentage == 2)
stimulus.perbaharuiStimulus("MAJU");
if (e.ProgressPercentage == 3)
stimulus.perbaharuiStimulus("");
stimulus.Show();
}
希望对您有所帮助!
我的项目 c# 中有 2 个表单(formA 和 formB),我想 运行 当我在 formA 中单击一个按钮时在后台工作程序中进行一些处理。
我可以从 backgroundworker 更新到 formB 中的标签吗? 这是formA
中的代码 private void button1_Click_1(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Stimulus stimulus = new Stimulus();
Stopwatch watch = new Stopwatch();
stimulus.Show();
stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus("+"); });
watch.Start();
do
{
} while (watch.Elapsed.Seconds != 2);
watch.Restart();
stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus("MAJU"); });
do
{
} while (watch.Elapsed.Seconds != 6);
watch.Restart();
stimulus.Invoke((MethodInvoker)delegate { stimulus.perbaharuiStimulus(""); });
do
{
} while (watch.Elapsed.Seconds != 2);
watch.Stop();
stimulus.Close();
}
这里是 formB 中的代码
public Stimulus()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
}
public void perbaharuiStimulus(string stimulus)
{
this.Invoke((MethodInvoker)delegate
{
lbStimulus.Text = stimulus;
});
}
谢谢关注..
您可以使用 Invoke(...)
从后台工作人员以任何形式更新标签,就像您所做的那样。 (假设刺激是一个领域)。
调用一次 Invoke 就足够了。 Stimulus.Invoke
在刺激形式的控制线程上执行委托。因此,您可以决定何时分派线程。我建议在 perbarauiStimulus
中执行此操作,因为这会减少有人忘记发送呼叫的可能性。
但是您的代码存在一个潜在问题:
不要对经过的时间使用精确比较。更喜欢使用“>=”。由于您处理的是秒,这很少会成为实际问题,但它可能会导致无限循环。
如果 stimulus
不是一个字段,您必须在后台工作程序的 Stimulus
外部 创建一个实例,因为如果您在内部创建它worker 方法,表单将 运行 它的消息在后台工作线程上循环。这消除了后台工作者的使用,因为操作 运行s 现在从 sytimulus 视图同步。
您不应该在后台线程中创建表单。这样做会将表单分配给 that 线程而不是 UI 线程,这意味着表单现在与消息泵位于不同的线程上。
解决此问题的方法是在 UI 线程上调用表单的实例化和查看,然后您的后续 Invoke
调用应该可以工作。
Stimulus stimulus;
this.Invoke((MethodInvoker)delegate
{
stimulus = new Stimulus();
stimulus.Show();
});
//No need to invoke this since perbaharuiStimulus() calls Invoke() as well.
stimulus.perbaharuiStimulus("+");
//The rest of your code...
除此之外,您做的一切都正确。
您可以像下面这样更改您的代码,它会正常工作。
将 perbaharuiStimulus 代码更改为
lbStimulus.Text = stimulus;
将
WorkerReportsProgress
改为True
将
backgroundWorker1_DoWork
改为以下Stimulus stimulus = new Stimulus(); Stopwatch watch = new Stopwatch(); backgroundWorker1.ReportProgress(1, stimulus); watch.Start(); do { } while (watch.Elapsed.Seconds != 2); watch.Restart(); backgroundWorker1.ReportProgress(2, stimulus); do { } while (watch.Elapsed.Seconds != 6); watch.Restart(); backgroundWorker1.ReportProgress(3, stimulus); do { } while (watch.Elapsed.Seconds != 2); watch.Stop(); stimulus.Invoke((MethodInvoker)delegate { stimulus.Close(); });
添加
backgroundWorker1_ProgressChanged
事件并在其中放入以下代码private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { Stimulus stimulus = ( Stimulus)e.UserState; if(e.ProgressPercentage==1) stimulus.perbaharuiStimulus("+"); if (e.ProgressPercentage == 2) stimulus.perbaharuiStimulus("MAJU"); if (e.ProgressPercentage == 3) stimulus.perbaharuiStimulus(""); stimulus.Show(); }
希望对您有所帮助!