DataGridView ArgumentOutOfRangeException

0
0

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!

  • You must to post comments
0
0

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 first data source is set to datasource1
  • Then the datasource is set to null and a new datasource is set.
  • When the datasource being set is used a second time, the BindingContext will update the current row to the last position in the data source but when the client sets the current row the server has already cleared the list.

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.

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.