|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
multithreaded grid-binding problemsHi 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 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 Show quote "Daniel Serra" <d.serra@avoidspam.com> wrote in message news:OQLWN3M4FHA.696@TK2MSFTNGP09.phx.gbl... > 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 > > 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 Show quote "Manoj G [MVP]" <manoj@nospam.com> wrote in message news:uA89KrP4FHA.1276@TK2MSFTNGP09.phx.gbl... > 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 > > "Daniel Serra" <d.serra@avoidspam.com> wrote in message > news:OQLWN3M4FHA.696@TK2MSFTNGP09.phx.gbl... >> 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 >> >> > > Hi Daniel,
Show quote "Daniel Serra" <d.serra@avoidspam.com> schreef in bericht I have a similar situation, where I use a producer/consumer pattern. The news:OQLWN3M4FHA.696@TK2MSFTNGP09.phx.gbl... > 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 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. 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! Show quote :D "TT (Tom Tempelaere)" </\/_0_$P@/\/\titi____AThotmailD.Tcom/\/\@P$_0_/\/> wrote in message news:6Vmbf.40820$OI1.2044026@phobos.telenet-ops.be... > Hi Daniel, > > "Daniel Serra" <d.serra@avoidspam.com> schreef in bericht > news:OQLWN3M4FHA.696@TK2MSFTNGP09.phx.gbl... >> 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. > Hi Daniel,
"Daniel Serra" wrote: I'll describe the control I made in which I used the pattern I described. > 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! 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, -- Tom Tempelaere. Hi again Daniel,
Show quote "TT (Tom Tempelaere)" wrote: Also note that for performance reasons, it is better to first delete the > > "Daniel Serra" wrote: > > 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. [...] 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, -- Tom Tempelaere |
|||||||||||||||||||||||