multithreaded grid-binding problems

D

Daniel Serra

Hi there (sorry for the cross-post),

I have a problem that I am not sure quite how to resolve. I have a series of
datasets, with grids being bound to any one of the datasets. These datasets
can get updated quite frequently (upwards of 10-20x per second, sometimes
just once a second), with each update often involving multiple row
addition/deletion as well updates. Originally I had the datasets created in
the same thread as the UI, which worked fine, but was a dog. What I would
like to do is have the dataset updates happen on another thread, and have
the grids show changes only once every 1/4 second (in effect throttling the
updates and allow for a more responsive UI). I have had limited success with
this as grid data sometimes seems to go missing, and was wondering if
anybody has had any experience in dealing with rapidly changing bound grids,
and if so what approaches you took?

Cheers
 
M

Manoj G [MVP]

Hi Daniel,

Are you updating the UI controls (binding ) on the right thread? If not, you
should be updating the UI controls on the thread that created them, by means
of calling Control.Invoke.

HTH,
Manoj G
MVP, Visual Developer
http://msmvps.com/manoj
 
D

Daniel Serra

yes, I did. I passed in a copy of the GetChanges in any event,
control.invoked and then merged the changes to the actual bound dataset
 
T

TT \(Tom Tempelaere\)

Hi Daniel,

Daniel Serra said:
Hi there (sorry for the cross-post),

I have a problem that I am not sure quite how to resolve. I have a series
of datasets, with grids being bound to any one of the datasets. These
datasets can get updated quite frequently (upwards of 10-20x per second,
sometimes just once a second), with each update often involving multiple
row addition/deletion as well updates. Originally I had the datasets
created in the same thread as the UI, which worked fine, but was a dog.
What I would like to do is have the dataset updates happen on another
thread, and have the grids show changes only once every 1/4 second (in
effect throttling the updates and allow for a more responsive UI). I have
had limited success with this as grid data sometimes seems to go missing,
and was wondering if anybody has had any experience in dealing with
rapidly changing bound grids, and if so what approaches you took?
Cheers

I have a similar situation, where I use a producer/consumer pattern. The
producer adds rows to a list, and a timer adds the rows from the list to the
grid by invoking a method that adds the rows. The reason I did this is
because of poor performance; DataGrid has a lot of events triggering and
updates going on if each row is added seperately (eats CPU time).

So basically what you need:
- a shared container that stores the produced rows
- a producer thread that adds the produced rows to the container
- a timer undocks the rows from the container (if any), and invokes a
method that adds these rows to the grid

Do not forget to synchronize access to the shared container. The timer
should undock the rows in the container, and invoke a method that adds the
rows to the grid. This method that adds the rows should do the following
before adding the rows:
- SuspendLayout on the DataGrid
- BeginLoadData on the DataTable
And do the following after adding the rows:
- EndLoadData on the DataTable
- ResumeLayout on the DataGrid

I chose the same timer interval as you did (250ms).

Hope this helps,
Tom Tempelaere.
 
D

Daniel Serra

Hi Tom,

Sounds like a great idea. However, how do you deal with deleted rows in the
case below? In the meantime I will try out the solution you describe below.
Cheers!

:D
 
G

Guest

Hi Daniel,

Daniel Serra said:
Sounds like a great idea. However, how do you deal with deleted rows in the
case below? In the meantime I will try out the solution you describe below.
Cheers!

I'll describe the control I made in which I used the pattern I described.
The control is a logging control that uses DataGrid for showing the logged
rows. Because DataGrid becomes slow if there are too many rows in the
DataTable bound to it, I restrict the number of rows that can appear.

Remember the method that adds the rows to the DataTable bound to the
DataGrid (the method that is invoked from the timer to effectively add the
rows). Also remember that I said to first call SuspendLayout (DataGrid) and
BeginLoadData (bound DataTable) before adding the rows. Well, the place where
you would add the rows, you would also delete the rows that should be deleted.

To illustrate, suppose my logging control has a maximum of 2000 entries, it
contains 1995 entries, and the timer finds 105 rows to be added to the
logging control. Before adding (appending) the 105 rows, I first delete the
first 100 rows in the DataTable then afterwards I add the 105 rows (yielding
a DataTable with exactly 2000 rows).

I'll rephrase my suggestion from my previous post:
" This method that adds/deletes rows should do the following before
adding/deleting the rows:
- SuspendLayout on the DataGrid
- BeginLoadData on the DataTable
And do the following after adding/deleting the rows:
- EndLoadData on the DataTable
- ResumeLayout on the DataGrid "

Hope this helps & kind regards,
 
G

Guest

Hi again Daniel,

TT (Tom Tempelaere) said:
Daniel Serra said:
Sounds like a great idea. However, how do you deal with deleted rows in the
case below? In the meantime I will try out the solution you describe below.
Cheers!
[...]

Remember the method that adds the rows to the DataTable bound to the
DataGrid (the method that is invoked from the timer to effectively add the
rows). Also remember that I said to first call SuspendLayout (DataGrid) and
BeginLoadData (bound DataTable) before adding the rows. Well, the place where
you would add the rows, you would also delete the rows that should be deleted.
[...]

Also note that for performance reasons, it is better to first delete the
rows, and then add the rows, well, at least it is better in my scenario but I
think it is generally the better way.

Kind regards,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top