BindingList зависает при вызове ResetBindings - PullRequest
1 голос
/ 30 апреля 2019

У меня есть класс, который создает и обновляет BindingList, который используется в качестве источника привязки для WinForms DataGridView. Форма создает экземпляр этого класса при загрузке. Затем класс (LotCache) создает список с типом LotCacheItem. Он обновляется каждые 20 секунд через фоновый рабочий поток. Он выполняет все обновление списка нормально, но когда я вызываю «DisplayArray.ResetBindings ()», он зависает и никогда не возвращается. Ниже приведен код для класса. Есть ли более простая междисциплинарная реализация, я что-то не так делаю?

    public class LotCache
{

    internal BackgroundWorker _fillPlantDataTable;
    private readonly DataGridView _frm;
    private Timer _gridRefresh;
    private BindingSource _source;


    /// <summary>
    /// Gets or sets the lots dictionary, which holds the lots for the forms usage
    /// </summary>
    /// <value>
    /// The lots dictionary.
    /// </value>
    public Dictionary<int, Lot> LotsDictionary { get; set; }

    /// <summary>
    /// The display array used by the Blood Pits data grid
    /// </summary>
    public BindingList<LotCacheItem> DisplayArray;

    /// <summary>
    /// Initializes a new instance of the <see cref="LotCache"/> class.
    /// </summary>
    /// <param name="dataGridView">The DataGridView that needs to be updated.</param>
    public LotCache(ref DataGridView dataGridView)
    {
        _frm = dataGridView;
        DisplayArray = new BindingList<LotCacheItem>();
        DisplayArray.AllowNew = true;
        DisplayArray.AllowRemove = true;
        DisplayArray.RaiseListChangedEvents = true;

        DisplayArray.ListChanged += DisplayListUpdated;
        _source = new BindingSource(DisplayArray, null);

        _fillPlantDataTable = new BackgroundWorker();
        _fillPlantDataTable.DoWork += FillDataTable;

        FillLocalDataTable();


    }
    private void FillLocalDataTable()
    {
        Get_ByHarvestDateLocal();

    }
    private void Get_ByHarvestDateLocal()
    {
        Lots _ls = new Lots();

        try
        {

            //This call gets lots from a local database
            DataTable _localLots = DataHelper.ExecuteProc("Local_LotCacheSelect", new ProcParams("HarvestDate", DateTime.Now));
            if (_localLots.Rows.Count > 0)
                DisplayArray.Clear();
            foreach (DataRow Row in _localLots.Rows)
            {
                Lot L = FillLots(Row);
                if (!_ls.ContainsKey(L.Lot_No))
                    _ls.Add(Row.Field<short>("Lot_No"), L);
            }

            LotsDictionary = _ls;
            StartGridRefresh();
        }
        catch (SqlException e)
        {
            MessageWindow.Show("Network Error", e.Message);
        }
    }

    /// <summary>
    ///     Get all Lots by harvest date.
    /// </summary>
    /// <param name="HarvestDate">The harvest date.</param>
    /// <returns>A <see cref="Lot" /></returns>
    private void StartGridRefresh()
    {
        int _refresh = 20;
        _gridRefresh = new Timer { Interval = _refresh * 1000 };
        _gridRefresh.Tick += GridRefresh_Tick;
        _gridRefresh.Enabled = true;
    }

    private void GridRefresh_Tick(object sender, EventArgs e)
    {
        if (!_fillPlantDataTable.IsBusy) //<------------This is always busy after first execution
            _fillPlantDataTable.RunWorkerAsync();
    }

    private void FillDataTable(object sender, DoWorkEventArgs e)
    {
        Debug.WriteLine("Im in fillDataTable: " + Thread.CurrentThread.ManagedThreadId + " " + DateTime.Now);
        try
        {


            DataTable _lotCacheTable = DataHelper.ExecuteProc("Local_LotCacheSelect", new ProcParams("HarvestDate", DateTime.Now));


            DisplayArray.RaiseListChangedEvents = false;
            Debug.WriteLine("Clear: " + Thread.CurrentThread.ManagedThreadId + " " + DateTime.Now);
            DisplayArray.Clear();
            Debug.WriteLine("End Clear: " + Thread.CurrentThread.ManagedThreadId + " " + DateTime.Now);
            foreach (DataRow Row in _lotCacheTable.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 = 0;

                DisplayArray.Add(_lc);
            }

            Debug.WriteLine("Grid Filled: " + Thread.CurrentThread.ManagedThreadId + " " + DateTime.Now);
            DisplayArray.RaiseListChangedEvents = true;

            DisplayArray.ResetBindings(); //<--Never Finishes
            Debug.WriteLine("Bindings Reset: " + Thread.CurrentThread.ManagedThreadId + " " + DateTime.Now);

        }
        catch (Exception _e)
        {
            //MessageWindow.Show("", _e.Message);
        }
    }
}

Вот LotCacheItem:

    public class LotCacheItem
{
    public int Lot_No { get; set; }
    public DateTime HarvestDate { get; set; }
    public int HeadCount { get; set; }
    public string ProducerName { get; set; }

    public string Age { get; set; }

    public string Cool { get; set; }

    public string CustomHarvest { get; set; }

    public int BloodPittedCount { get; set; }


}

Я надеюсь, что предоставил достаточно информации, если нет, пожалуйста, дайте мне знать, и я предоставлю, что могу ... Опять же, все отлично заполняется, но никогда не попадает в отладочную запись после вызова ResetBindings в FillLocalDataTable, в результате чего фоновый работник отображается как «Занят» и никогда не запускается после начальной загрузки.

...