C# 未按顺序发生的事件
我正在用C#创建一个WinForms应用程序。当我点击一个按钮时,一个特定的事件流应该会发生:C# 未按顺序发生的事件,c#,winforms,backgroundworker,C#,Winforms,Backgroundworker,我正在用C#创建一个WinForms应用程序。当我点击一个按钮时,一个特定的事件流应该会发生: 点击按钮 显示标签1 显示标签2 调用函数解析用户之前输入的字符串(这可能需要一段时间,具体取决于字符串) 显示listBox1和progressBar1 backgroundWorker1.RunWorkerAsync backgroundWorker1_DoWork()执行x次操作并每次报告进度 backgroundWorker1_ProgressChanged()更新progressBar1并
- 点击按钮
- 显示标签1
- 显示标签2
- 调用函数解析用户之前输入的字符串(这可能需要一段时间,具体取决于字符串)
- 显示listBox1和progressBar1
- backgroundWorker1.RunWorkerAsync
- backgroundWorker1_DoWork()执行x次操作并每次报告进度
- backgroundWorker1_ProgressChanged()更新progressBar1并向listBox1添加一项
- backgroundWorker1\u RunWorkCompleted()显示一个消息框,显示“完成”
private void button1_Click(object sender, EventArgs e){
label1.Show();
label2.Show();
String errMsg = parseString();
if (errMsg == ""){
listBox1.Items.Clear();
listBox1.Show();
progressBar1.Maximum = 100;
progressBar1.Step = 1;
progressBar1.Value = 0;
progressBar1.Show();
backgroundWorker1.DoWork += backgroundWorker1_DoWork;
backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
backgroundWorker1.ReportProgress(1, "Updating Devices");
for (int i = 0; i < 100; i++)
{
//todo: do stuff
//update progress
backgroundWorker1.ReportProgress(i, "Device:" + i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
listBox1.Items.Add(e.UserState);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("DONE");
}
private void按钮1\u单击(对象发送者,事件参数e){
label1.Show();
label2.Show();
String errMsg=parseString();
如果(errMsg==“”){
listBox1.Items.Clear();
listBox1.Show();
progressBar1.最大值=100;
progressBar1.步骤=1;
progressBar1.值=0;
progressBar1.Show();
backgroundWorker1.DoWork+=backgroundWorker1_DoWork;
backgroundWorker1.ProgressChanged+=backgroundWorker1\u ProgressChanged;
backgroundWorker1.RunWorkerCompleted+=backgroundWorker1\u RunWorkerCompleted;
backgroundWorker1.WorkerReportsProgress=true;
backgroundWorker1.WorkerSupportsScanCellation=true;
if(backgroundWorker1.IsBusy!=true)
{
backgroundWorker1.RunWorkerAsync();
}
}
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
backgroundWorker1.报告进度(1,“更新设备”);
对于(int i=0;i<100;i++)
{
//托多:做事
//更新进度
backgroundWorker1.报告进度(i,“设备:+i”);
}
}
私有void backgroundWorker1\u ProgressChanged(对象发送方,ProgressChangedEventArgs e)
{
progressBar1.值=e.ProgressPercentage;
listBox1.Items.Add(如UserState);
}
私有void backgroundWorker1\u RunWorkerCompleted(对象发送方,runworkercompletedeventarge)
{
MessageBox.Show(“完成”);
}
感谢@HansPassant和@mjwills的评论。他们引导我走上了正确的道路,使这个解决方案成为可能
最后,我决定做两个后台工作来解决label1和label2直到解析完成后才出现的问题。我使用第一个来做解析,第二个来做“dostuff”部分。在代码中,您将看到我必须使用Invoke来编辑标签,因为该部分现在存在于不同的线程中
我还意识到,在调用ProgressChanged之前“做一些事情”并不是立即的。我一直在分块开发,尚未实现该代码,但我知道这些操作至少需要3秒钟才能完成(部分原因是涉及ping)。所以现在我在这个循环中加入了一个Sleep(3000)调用来模拟它的实际行为。这解决了由于耗尽所有内存而导致的奇怪progressbar1和listbox1行为
下面是代码的结果:
private void button1_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
String errMsg = parseString();
if (errMsg == "")
{
if (listBox1.InvokeRequired)
{
listBox1.Invoke(new MethodInvoker(delegate
{
listBox1.Items.Clear();
listBox1.Show();
}));
}
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke(new MethodInvoker(delegate
{
progressBar1.Maximum = 100;
progressBar1.Step = 1;
progressBar1.Value = 0;
progressBar1.Show();
}));
}
if (backgroundWorker2.IsBusy != true)
{
backgroundWorker2.RunWorkerAsync();
}
}
else
{
MessageBox.Show(errMsg);
}
}
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
backgroundWorker2.ReportProgress(1, "Updating Devices");
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(3000);
//do stuff
backgroundWorker2.ReportProgress(i, "Device:" + i);
}
}
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke(new MethodInvoker(delegate
{
progressBar1.Value = e.ProgressPercentage;
}));
}
if (listBox1.InvokeRequired)
{
listBox1.Invoke(new MethodInvoker(delegate
{
listBox1.Items.Add(e.UserState);
}));
}
}
private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("DONE");
}
private void按钮1\u单击(对象发送者,事件参数e)
{
if(backgroundWorker1.IsBusy!=true)
{
backgroundWorker1.RunWorkerAsync();
}
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
String errMsg=parseString();
如果(errMsg==“”)
{
如果(listBox1.InvokeRequired)
{
listBox1.Invoke(新方法调用器(委托
{
listBox1.Items.Clear();
listBox1.Show();
}));
}
如果(progressBar1.InvokeRequired)
{
progressBar1.Invoke(新方法调用器(委托
{
progressBar1.最大值=100;
progressBar1.步骤=1;
progressBar1.值=0;
progressBar1.Show();
}));
}
if(backgroundWorker2.IsBusy!=true)
{
backgroundWorker2.RunWorkerAsync();
}
}
其他的
{
MessageBox.Show(errMsg);
}
}
私有void backgroundWorker2_DoWork(对象发送方,DoWorkEventArgs e)
{
backgroundWorker2.报告进度(1,“更新设备”);
对于(int i=0;i<100;i++)
{
系统线程线程睡眠(3000);
//做事
backgroundWorker2.报告进度(i,“设备:+i”);
}
}
private void backgroundWorker2\u ProgressChanged(对象发送方,ProgressChangedEventArgs e)
{
如果(progressBar1.InvokeRequired)
{
1.在