Home > Net >  A BackgroundWorker returning null without Exception error when the same operations done outside of i
A BackgroundWorker returning null without Exception error when the same operations done outside of i

Time:01-07

I have a few BackgroundWorkers all doing the same task in a TabPage : they pull data from a MySql database and upon completion they update the BindingSource of a Chart.

One of them started acting up lately. Here is the code:

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();
}

Now oddly enough, since I can't step through the BackgroundWorker_DoWork event, if I copy the code into the RunWorkerCompleted as shown below, then I get real data, not 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();
}

How is this possible? How can the same code return a null value in one thread and a set of data in another?

The only changes I've made to the code lately in this section is the added if (e.Result!=null) section, because there was no data for the current month and when the Sort property was set, it would throw an exception error. But now there is data, it's just not seeing it. It's been working well for months. Other than this month being a new year, nothing else has changed. At first I thought the MySQL View was flawed, but nope.

Any thoughts on why or even how I can figure out where the problem is?

CodePudding user response:

Diagnosis of this one in comments under the question, turned out that the DoWork event handler code had become un-bound from the DoWork event. I've had this happen from time to time for various controls as I work with the designer..

The code lens for reference count can also be a hint to this:

enter image description here

Incidentally, I'd say your code might be collapsible to just this:

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 should always return a datatable even if it's empty, so you might be able to skip the null check

Also, maybe you already know but you can always right click your TableAdapter in your dataset and add more queries that do other filtering so a query of

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

Would save those records being downloaded in the first place. Give the query a good name when asked, like FillAllExceptZeroTotal / GetDataByAllExceptZeroTotal and you can

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;
}
  •  Tags:  
  • Related