У меня есть класс, который создает и обновляет 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, в результате чего фоновый работник отображается как «Занят» и никогда не запускается после начальной загрузки.