一个 BackgroundWorker returning null,当在它之外完成相同的操作时没有异常错误 return 一个值

A BackgroundWorker returning null without Exception error when the same operations done outside of it return a value

我有一些 BackgroundWorkers 都在 TabPage 中执行相同的任务:他们从 MySql 数据库中提取数据完成后,他们会更新 Chart.

BindingSource

他们中的一个人最近开始胡作非为。这是代码:

private void bgwRefreshChartMoisCourant_DoWork(object sender, DoWorkEventArgs e)
{
      trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable dT = new trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable();

      this.viewventesparutilisateurmoiscourantTableAdapter.Fill(dT);
      e.Result = dT;
}

private trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable salesThisMonthDataTable = new trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable();

private void bgwRefreshChartMoisCourant_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
      salesThisMonthDataTable = new trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable();
      salesThisMonthDataTable = (trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable)e.Result;

      this.viewventesparutilisateurmoiscourantBindingSource.DataMember = "";
      this.viewventesparutilisateurmoiscourantBindingSource.DataSource = salesThisMonthDataTable; 
            
      // If the sales are null at the beginning of a month, the filter and sorting will throw an error
      if (e.Result!=null)
      {
          this.viewventesparutilisateurmoiscourantBindingSource.Filter = "Total<>0 AND Vendeur<>'Total'";
          this.viewventesparutilisateurmoiscourantBindingSource.Sort = "Total ASC";
      }

      this.chartSalespersonsThisMonth.DataSource = this.viewventesparutilisateurmoiscourantBindingSource;
      this.chartSalespersonsThisMonth.DataBind();
}

现在很奇怪,因为我无法单步执行 BackgroundWorker_DoWork 事件RunWorkerCompleted如下图,然后我得到的是真实数据,不是null.

private void bgwRefreshChartMoisCourant_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
      // Temporary fix for Background Worker e.Result which is null for some reason, with no Exception error thrown (e.Cancel and e.Error are both null)
      trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable dT = new trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable();
      this.viewventesparutilisateurmoiscourantTableAdapter.Fill(dT);

      salesThisMonthDataTable = new trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable();
      salesThisMonthDataTable = (trimlineSalesReportDataSet.viewventesparutilisateurmoiscourantDataTable)e.Result;

      this.viewventesparutilisateurmoiscourantBindingSource.DataMember = "";
      this.viewventesparutilisateurmoiscourantBindingSource.DataSource = dT;      // Temporary fix
            
      // If the sales are null at the beginning of a month, the filter and sorting will throw an error
      if (e.Result!=null)
      {
          this.viewventesparutilisateurmoiscourantBindingSource.Filter = "Total<>0 AND Vendeur<>'Total'";
          this.viewventesparutilisateurmoiscourantBindingSource.Sort = "Total ASC";
      }

      this.chartSalespersonsThisMonth.DataSource = this.viewventesparutilisateurmoiscourantBindingSource;
      this.chartSalespersonsThisMonth.DataBind();
}

这怎么可能?同样的代码怎么可能return在一个线程中是空值而在另一个线程中是一组数据呢?

我最近对本节中的代码所做的唯一更改是添加了 if (e.Result!=null) 部分,因为当月没有数据并且 Sort 属性 被设置,它会抛出异常错误。但是现在有数据了,只是没看到而已。几个月来一直运作良好。除了这个月是新年之外,其他都没有改变。起初我认为 MySQL 视图 有缺陷,但没有。

关于为什么甚至如何找出问题所在的任何想法?

在问题下的评论中对此进行诊断,发现 DoWork 事件处理程序代码已从 DoWork 事件中解除绑定。当我与设计师一起工作时,我不时遇到这种情况的各种控件..

引用计数的代码镜头也可以对此有所提示:

顺便说一句,我想说你的代码可能只是这样折叠的:

private void bgwRefreshChartMoisCourant_DoWork(object sender, DoWorkEventArgs e)
{
      e.Result = this.VenParMoisCourTableAdapter.GetData();
}

private void bgwRefreshChartMoisCourant_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
      this.VenParMoisCourBindingSource.DataSource = e.Result;
      
      this.VenParMoisCourBindingSource.Filter = "Total<>0 AND Vendeur<>'Total'";
      this.VenParMoisCourBindingSource.Sort = "Total ASC";
}

GetData 应该总是 return 一个数据表,即使它是空的,所以你可以跳过 null 检查

此外,也许您已经知道,但您始终可以右键单击数据集中的 TableAdapter 并添加更多执行其他过滤的查询,因此查询

SELECT * FROM VenParMoisCour WHERE Total<>0 AND Vendeur<>'Total' ORDER BY Total

首先保存正在下载的记录。在询问时为查询取一个好名字,例如 FillAllExceptZeroTotal / GetDataByAllExceptZeroTotal,您可以

private void bgwRefreshChartMoisCourant_DoWork(object sender, DoWorkEventArgs e)
{
      e.Result = this.VenParMoisCourTableAdapter.GetDataByAllExceptZeroTotal();
}

private void bgwRefreshChartMoisCourant_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
      this.VenParMoisCourBindingSource.DataSource = e.Result;
}