I currently have an ultragrid that is bound to a DataSet containing a number of DataTables.
I update this grid by merging an updated DataSet with my current DataSet. This seems to work OK, however the merge takes 3 seconds, during which time the ultragrid is unresponsive. Seeing as I'm updating the data every 10 seconds that means my grid is unusable for 30% of the time which is a bit of a problem for the user.
Is there a way to merge the DataSet without hanging the grid?
Charlie
Try grid.BeginUpdate() and grid.SuspendRowSynchronization()
Don't forget to reenable them in finally{} clause
Dacos,
Thanks for your post, I am already using BeginUpdate and SuspendRowSynchronization
Well, it's hard to be more specific without source code and without explanation, why you actually need to merge datasets each 10 seconds.
You can try to merge only specific tables, not the whole dataset.
If the dataset is not changeable by user, you can try maintaining two copies of datasets, make merge on a separate thread and rebind the grid to the second dataset when the merge is done (thus switching datasets).
Are there a lot of DataColumn expressions? You can try to remove them, do merge and then reestablish them (the DataSet merge doesn't do it for you. Checked on .NET Framework 2.0).
Once more, it is hard to be specific not having any specific input data from you :)
Really appreciate you thorough reply, if I can give you a little more info:
>>why you actually need to merge datasets each 10 seconds.The underlying data is live price data that is changing constantly, the user needs this data to be up to date (more than 10 seconds and the data would be too out of date)
>>You can try to merge only specific tables, not the whole dataset.Each DataTable in the DataSet has a parent DataTable with summary information, so as the detail in the bottommost DataTable changes, so the summary information in the parent DataTable is updated. We tried getting the grid to do the grouping itself but it runs like a dog and performance is unacceptable. Using hierachical DataSet solves alot of problems for us, however the DataSet.Merge is not scaling very well.
>>If the dataset is not changeable by user, you can try maintaining two copies of datasets, make merge on a separate thread and rebind the grid to the second dataset when the merge is done (thus switching datasets).You're right, I tried this but when you rebind the grid to the second dataset the grid effectively resets itself which opens up a can of worms (rows don't stay expanded, the scroll position changes, etc) I saw a post elsewhere on the forum advising against doing this. I gues it's a bit like taking a sledgehammer ot the grid
Are there a lot of DataColumn expressions? You can try to remove them, do merge and then reestablish them (the DataSet merge doesn't do it for you. Checked on .NET Framework 2.0).Yes there are a few expressions, maybe this is one area I could look at.
Once more, it is hard to be specific not having any specific input data from you :)No you brought up some very relevant points, I appreciate that. If you would like a short summary of my data structure I'll be happy to post it.
Thanks
1. As far as I remember, there was already a discussion of representation of online data in a WinGrid/WinChart. Mike has made a couple of good suggestions there. I couldn't find the thread, but may be you'll have more luck. Try searching the forum (sorry for banal suggestion)
2.
openshac said:Using hierachical DataSet solves alot of problems for us, however the DataSet.Merge is not scaling very well.
The problem is also that Merge will become slower and slower as the destination dataset will grow. Maybe the Merge is just not a right (too trivial) solution in your case. You'll probably need some method which freezes the grid, removes old and adds new rows. Merge has also pretty much overhead for analysing of structure of datatables and so on.
You'll also be able to transfer some preparations (creation of DataRows etc.) to a separate thread. Only adding to datatable(s) which is (are) bound to the grid need to be synchronized with the UI thread. I would try it without separate thread first. Maybe the performance will be already good enough
3.
openshac said:You're right, I tried this but when you rebind the grid to the second dataset the grid effectively resets itself which opens up a can of worms (rows don't stay expanded, the scroll position changes, etc) I saw a post elsewhere on the forum advising against doing this.
Well, it's all doable, but you're right, it's pain in the neck. I would leave this way as a last solution
4,
openshac said:If you would like a short summary of my data structure I'll be happy to post it.
You could try disabling/reenabling expressions and doing merge yourself first. If this doesn't bring satisfactory improvement, it wouldn't harm to see your datastructure, some source code and profiling results
Well after some investigation I came to the conclusion that the problem probably lies with the DataSet merge, not the grid.
Since the DataSet that I am merging is bound to the grid (which is on the GUI thread) the merge has to be performed on the GUI thread. If you try and do it asynchoronously on another thread you get a whole load of grid errors as rows get unexpectedly changed/inserted/deleted.
Now since the merge has to be run on the GUI thread, the GUI will freeze until the merge has completed.
Now if Microsoft made the DataSet merge a bit quicker then maybe I wouldn't get these sort of problems.
Alternatively if I could find a way of disconnecting the grid BindingSource completely whilst I do the merge then that would do the trick (SuspendBinding and ResumeBinding don't help me unfortunately)
Thanks for all your help
There's a good discussion of this at: http://forums.infragistics.com/forums/p/15832/57858.aspx#57858
Now THAT is clever, will have to have a look and investigate.
This is a "live" screenshot. If the control is not resized - the user doesn't actually see the difference (the grid is just "locked"). When resizing a gray background is visible. Acceptable for us (we didn't have much choice honestly saying :) )
Bitmap bitmap = new Bitmap(control.Width, control.Height);control.DrawToBitmap(bitmap, Rectangle.FromLTRB(0, 0, bitmap.Width, bitmap.Height));disabledGridPictureBox.Image = bitmap;disabledGridPictureBox.Dock = DockStyle.Fill;disabledGridPictureBox.SizeMode = PictureBoxSizeMode.Normal;disabledGridPictureBox.BringToFront();
dacos_sscherer001 said:grid invisible replacing it with a screenshot
I presuming this is a predetermined screen shot, right, not a "live" screenshot?
As you can see, I am the author of the thread you mentioned ;)
Our application ended in calling BeginUpdate(), SuspendRowSynchronization(), grid.Enabled = false; ___ and we also make the grid invisible replacing it with a screenshot__.
This whole "there is no good solution, try to shoot out of all guns you have" works for us (we could not reproduce any thread issues and AFAIK have not had any bug reports from our user which could result from synchronisation problems). At least the client is not freezed during the operation, and the user can access other parts of our application.
There is no guarantee that this hack will work for you. Of course it would be a good idea to try to solve the issue with "normal" means.