1

I have a UI class and a Class representing the calls I need to fill the UI Classes DGV. When I call Bindinglist.Clear() inside the worker class, I get a cross thread operation exception for the DGV. I've looked at the .Invoke suggestions, but I don't understand where I'd put it since the error is being raised in the worker class.

Heres the worker class. DisplayArray is a static binding list:

private void Get_ByHarvestDate(DateTime HarvestDate)
{
    try
    { 
    Lots Ls = new Lots();


    DataTable _plantLots = DataHelper.ExecuteProc("[Abattoir].[Lots_Select_ByHarvestDate]",
        new ProcParams("HarvestDate", HarvestDate), DataBaseMaster.PlantConnectionString);

    if (_plantLots.Rows.Count > 0)
        DisplayArray.Clear();//<---error here
    foreach (DataRow Row in _plantLots.Rows)
    {
        Lot L = FillLots(Row);
        // if (!Ls.ContainsKey(L.Lot_No))
        Ls.Add(L.Lot_No, L);
    }

    foreach (DataRow Row in _plantLots.Rows)
    {
        LotCacheItem _lc = new LotCacheItem();
        _lc.Lot_No = Row.Field<short>("Lot_No");
        _lc.HeadCount = Row.Field<int>("HeadCount");
        _lc.ProducerName = Row.Field<string>("Producername");
        _lc.BloodPittedCount = GetBloodPittedCount(_lc.Lot_No);
        DisplayArray.Add(_lc);
    }
    LotsDictionary?.Clear();
    LotsDictionary = Ls;
    }
    catch (Exception _e)
    {
        MessageWindow.Show("", _e.Message);
    }
}

_plantLots is just a datatable from a query, so when it has rows, I'd like to clear the list and refill.

Here is the UI classes ListChanged Handler:

private void HandleGridUpdate(object sender, EventArgs e)
{
    try
    {
        DgvLots.AutoGenerateColumns = false;
        DgvLots.DataSource = null;
        DgvLots.DataSource = LotCache.DisplayArray;
        lotDisplay_Current.UpdateLot(_currentLot);
        SelectGridRow(_currentLot.Lot_No);
    }
    catch (Exception _e)
    {
        MessageWindow.Show("", _e.Message);
    }
}

I don't understand why I'm getting this error (I assume it's in the ListUpdated callback) and that makes it hard to apply a fix.

FaizanHussainRabbani
  • 3,256
  • 3
  • 26
  • 46
rigamonk
  • 1,179
  • 2
  • 17
  • 45
  • 5
    Possible duplicate of [How do I update the GUI from another thread?](https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread) – Peter Bons Mar 01 '18 at 14:31
  • You just cannot interact with the UI thread from any other thread. So you have to perform `DisplayArray.Clear();` somewhere else or use 'Invoke'. Can't you switch to the async/await pattern? Makes things easier to follow. – Peter Bons Mar 01 '18 at 14:32
  • But the binding list has a baked in event handler for this, so I see this as a bit different, imho – rigamonk Mar 01 '18 at 14:33
  • Well, you cannot beat the system, so even if you might see it different you can't really argue with the framework, trust me. Please post the method containing the call to `if (_plantLots.Rows.Count > 0) DisplayArray.Clear();//<--error here.` – Peter Bons Mar 01 '18 at 14:34
  • Can't you just wrap it into `Dispatcher.Invoke(() => {...});` or `SynchronizationContext.Current.Send(_ => { ... }, null);` – FCin Mar 01 '18 at 14:41
  • WPF / UWP / WinForms ? Anyway, check carefully for any async calls in the entire database/logic chain. – H H Mar 01 '18 at 14:52

0 Answers0