c# - BindingList 挂起 ResetBindings 调用
问题描述
我有一个类,它创建和更新用作 WinForms DataGridView 的绑定源的 BindingList。表单在加载时实例化此类。然后类 (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; }
}
我希望我已经提供了足够的信息,如果没有,请告诉我,我会提供我能提供的...再次,一切都很好,但是在 FillLocalDataTable 中的 ResetBindings 调用之后它从未命中调试写入,导致后台工作人员显示为“忙碌”,并且在初始加载后永远不会解雇。
解决方案
推荐阅读
- firebase - 为什么 Firestore 无法进行聚合操作?
- flutter - 需要在使用 Flutter 的 OnDestroy 应用程序上执行一些代码
- ios - 在协议委托iOS本机代码中接收数据后如何将数据发送回Flutter应用程序?
- azure - Azure:将应用程序网关用于自定义 B2C 域而不是 Front Door
- c++ - 如何解决 opencv_highgui_gtk453_64.dll 问题?
- sql - SQL MAX() 函数似乎截断了结果
- php - 我们可以在 laravel 的队列中有两个实例“失败”吗?
- python - 使用 VNC 查看器时,模块 screeninfo 无法捕获屏幕分辨率
- html - 如何在 Bootsrap 5 中将行向右移动?
- post - SIM800L GPRS模块与ESP32接口如何自动选择APN