Hi,
I've searched a little bit in this form and can't find a clear match.
I'm dynamically adding and removing columns from the datasource backing a grid. I am experiencing huge delays. I've tried using SuspendRowSync, SuspendLayout and SuspendCalc properly contained within a BeginUpdate and try finally block with an EndUpdate (I didn't forget the appropriate Resume call). However none of these alleviate the performance problem.
I looked at the Grid Performance Guide and nothing jumped out at me.
I've used the Red Gate performance profiler to track down the performance issue. See attached compressed file that contains the call graph locked at the function occupies 89% of the time. In that function, it spends a majority of the time in Add/Remove columns on the UltraDataSource. Also it's clear that it's triggered a recalc and the recursive descent parser is parsing the calc code for the grid.
How can I improve the performance here? Perhaps I misapplied SuspendCalc? Can I force the CalcManager to fire once and statically create the code for the computations and not recompute them again?
Any suggestions are appreciated.
Craig
Hi Craig,
A screen shot of the profiler results isn't much help. But from what little I can see here, it looks like SuspendCalc would help.
It could be that the SuspendCalc is not helping because the grid is responding to the changes in the column structure asynchronously. So your ResumeCalc may have already been called before any of the processing by the grid begins. The same might be true of the calculations. Since the calculations are performed Asynchonrously, they might not be happening until after you call ResumeCalc.
It's very hard to guess without seeing the problem first-hand. Can you post a small sample project demonstrating the issue?
If not, then my suggestion would be to try setting the CalcFrequency on the CalcManager to Manual. That should prevent all calculations from occurring.
You should still use BeginUpdate and EndUpdate around the code that adds/removes the columns. And don't reset the CalcFrequency back to normal until after the EndUpdate.
I don't think SuspendRowSynrchonization will help, but I could be wrong, and it can't hurt. But SuspendLayout will not do anything, so you don't need that.
Also, it might be a good idea to use AddRange to add all of the columns at once instead of one at a time, if you can.
Hi Mike,
First thank you for the response.
I tried changing the CalcFrequency to Manual and reset the frequency back to normal after the EndUpdate. But, alas, that had no effect on performance. I need to rewrite a larger portion of the code to attempt using AddRange. I'll post later on how that goes.
As to SuspendRowSynchronization, I tried that as well but it had no effect.
I'm very surprised that Changing CalcFrequency to Manual didn't help. That seems to indicate that this is a grid issue.Did you profile the application with this change to see if the performance hit is still being caused by the same code?
This is not a good solution, but just as a test, it might be interesting to try completely disconnect the grid from the CalcManager.
this.ultraGrid1.CalcManager = null;
And then, of course, reset it back after the process completes.
Also, as I said, if you can duplicate this in a small sample project, I'm sure we could track down exactly what's going on.
I did indeed profile the issue with the CalcFrequency set to manual and the bottleneck still was in the Add/Remove of columns.
Unfortunately this situation is in a rather complex piece of code. I'm not ready, yet, to expend the effort to isolate the code to produce a standalone example. I'll try your other suggestions today.
Mike,
I disconnected the CalcManager from the grid and the perf issue has gone away. How is this not a good solution?
I understand how this might not be good for Infragistics as it doesn't identify the cause, but it does provide a timely solution for my customer base.
I'm happy to work in private with your engineers to address this problem in detail, however I need to ship a solution. Does setting the CalcManager to null for the duration of the GUI update impact the correctness of the data or stability of the application?
I guess if it works for you, then it's a good solution. Just seems a little unsatisfying to me. :)
What I meant is that it's not a solution because you should not have to do that. At best, it's a workaround.