背景工作者 – 报告与字符串数组的进展

我需要在每个循环中从我的backgroundworker返回多个STRING值,所以我尝试使用ReportProgress第二个参数作为字符串数组。 代码示例:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string[] workerResult = new string[2]; for (int i=0; i<someNumber; i++) { //do some heavy calculating workerResult[0] = "this string"; workerResult[1] = "some other string"; backgroundWorker1.ReportProgress(i, workerResult) // also tried workerResult[] and [2] } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { string[] results = (string[])e.UserState; MessageBox.Show(results[0]); // line of error MessageBox.Show(results[1]); // line of error } 

它编译,但在运行时,我尝试访问Userstate返回的字符串,我得到一个错误:“对象引用未设置为对象的实例。”

对我来说,似乎在将数组参数传递给ProgressChanged委托时出错,或者在尝试设置结果数组值时在ProgressChanged方法中出错。

您的代码段无法重现问题。 标准错误是调用ReportProgress()然后继续修改对象。 事件处理程序运行需要一段时间,它将看到修改后的对象,而不是原始对象。 您可以通过简单地创建一个新对象来避免这种情况,以便事件处理程序始终使用原始对象。 像这样:

  //do some heavy calculating for (int i = 0; i < 2; ++i) { string[] workerResult = new string[2]; workerResult[0] = "this string"; workerResult[1] = "some other string"; backgroundWorker1.ReportProgress(i, workerResult); } 

注意数组创建语句如何在循环内移动。

当您实例化BackgroundWorker时,您必须将reportprogress设置为true:

 worker = new BackgroundWorker { WorkerReportsProgress = true }; 

在do work方法上你只需要这个:

  worker.ReportProgress(10, "Message"); 

然后这样的事情来抓住进展:

 private void WorkerProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.UserState != null) { MessageBox.Show(e.UserState); } } 

我已经通过向后台工作程序添加一个新的ProgressChanged事件侦听器解决了类似的问题,如果未触发ProgressChanged ,则阻止传递到下一个循环:

 bool progressed; backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); string[] workerResult = new string[2]; for (int i = 0; i < 2; ++i) { progressed=true; workerResult[0] = "this string"; workerResult[1] = "some other string"; backgroundWorker1.ReportProgress(i, workerResult); while (progressed) { //you can add a thread sleep } } void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressed = false; }