我有一个创建和更新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; }
}
我希望我提供了足够的信息,如果没有,请让我知道,我将尽力提供... 同样,一切都可以正常运行,但是在FillLocalDataTable中的ResetBindings调用之后,它永远不会达到调试写入状态,从而导致后台工作程序显示为“忙碌”,并且在初始加载后再也不会触发。