Hi all,
we are having some problems with DataGridView.
We need to keep DGV updated between clients, so when a client change somethings the changes reflects on every client. To notify every client that somethings is changed, we used RabbitMQ. We send a message in brodcast and every client receive that message with what is change and can update itself.
We used this method to be sure that DGV update with new DataSource is a safe operation
private void SetDataSource(DataGridView grid, object dataSource)
{
lock (grid)
{
grid.BeginUpdate();
grid.DataSource = null;
grid.DataSource = dataSource;
grid.EndUpdate();
}
}
I attached a example, in this example i simulated two task that try to update the same datagridview. Pressing the “Refresh button” fast sometimes random i’m getting ArgumentOutOfRangeException
Here stacktrace:
in Wisej.Web.DataGridView.SetCurrentCellAddressCore(Int32 columnIndex, Int32 rowIndex, Boolean validateCell, Boolean updateCurrentCell, Boolean fromClient, Boolean selectCell)
in Wisej.Web.DataGridView.OnRowsAdded(Int32 rowIndex, Int32 rowCount)
in Wisej.Web.DataGridViewRowCollection.AddCopiesInternal(DataGridViewRow rowTemplate, Int32 count)
in Wisej.Web.DataGridView.RefreshRows()
in Wisej.Web.DataGridView.RefreshColumnsAndRows()
in Wisej.Web.DataGridView.OnDataSourceChanged(EventArgs e)
in Wisej.Web.DataGridView.set_DataSource(Object value)
in WisejWebPageApplication1.Page1.SetDataSource(DataGridView grid, Object dataSource)
in WisejWebPageApplication1.Page1.b__6_3()
in Wisej.Web.Application.<>c__DisplayClass293_0.b__0()
in Wisej.Web.Application.RunInContext(IWisejComponent context, Action action)
in Wisej.Web.Application.Update(IWisejComponent context, Action action)
in WisejWebPageApplication1.Page1.b__6_1()
in Wisej.Web.Application.<>c__DisplayClass290_0.b__0()
in System.Threading.Tasks.Task.InnerInvoke()
in System.Threading.Tasks.Task.Execute()
Thanks for any suggestions!
In the sample you are starting 3 threads that populate the datagrid one after the other causing a full refresh each time. They are synchronized by locking the grid object, which is ok. The problem is that you don’t change the data source and internally the BindingContext preserves the position of the current record and also that when on the web the events are all asynchronous.
This is what’s happening:
The solution is to adding a new data source object either by creating a new List<> or a new BindingSource and to populate it when it’s not assigned, otherwise Wisej will update the grid while it’s bound to the datasource. Try this change:
private void SetDataSource(DataGridView grid, List<ViewPratiche> dataSource) { lock (grid) { grid.BeginUpdate(); try { grid.DataSource = null; LoadDataSource(dataSource, 10000); grid.DataSource = new BindingSource(dataSource, ""); } finally { grid.EndUpdate(); } } }
And don’t call LoadDataSource on the data source while it’s bound.
Let me know.
Please login first to submit.