I have run across a particularly nasty bug that I can not work out for myself. Under some special conditions my grouping grid will get into an infinite loop. When this happens, the load on the computer goes to 100. Also, the Application.Idle event is raised repeatedly (several hundred times per second) even though there are no mouse or keyboard input. Unfourtunately I have not been able to isolate a simple test program where this occurs, but I have observed the following:
- I have an Application.Idle handler in my program. The abnormal behaviour seems to be triggered after my handler has done a fairly length computation. My handler only does the lenghty compuation once. After that it does no significant work. However this seems to trigger an infinite loop in the grid that leads to repeaded Application.Idle events and load 100.
- If I close the form with the grid on, the load immediately goes back to normal.
- If I collapse all groups in the grid, the load immediately goes back to normal.
- In my code I call the gridRecord.SetCurrent() method. If I never do this call, the grid will not get into the abnormal state. (Unfourtunately I need to do this call to syncronize the grid with the CurrencyManager of the underlying DataView because the default grid implementation will not always do this when it is grouped, as discussed in a previous post.)
I suspect that there is an Application.Idle handler in the grid that under some conditions will keep doing leghty computaionts and make the load go to 100. I really need a workaround for this. If you have any suggestions for what the cause may be or a suggested workaround, I would be very happy.
I am using version 3.2.1.0.
AD
Administrator
Syncfusion Team
November 28, 2005 09:05 AM UTC
Try setting
ScrollControl.DiscardPaintMessagesAfterBeginUpdate = true;
It is a static memner of ScrollControl class.
These are the remarks that go with that property:
/// When you call BeginUpdate(), the control by default does not handle WM_PAINT messages. Only
/// once you call EndUpdate they will be processed. If this causes problems in your application, you can
/// set this static property to True. In such cases, WM_PAINT messages will be simply discarded and
/// any invalid regions will be validated.
/// There is a problem with the default implementation of BeginUpdate. If a screen region is marked
/// invalid, the WndProc will be repeatedly called with WM_PAINT at the the top of the WndProc
/// until EndUpdate is called. This can cause your application to freeze if another window gets created
/// or if you make a web service call and WndProc messages need to be processed.
/// Setting DiscardPaintMessagesAfterBeginUpdate to True will help avoid these scenarios.
AD
Administrator
Syncfusion Team
November 28, 2005 09:17 PM UTC
Setting this property didn''t help. I still had the same problem. Also, after setting this property, my xp-menus didn''t paint properly.
AD
Administrator
Syncfusion Team
November 28, 2005 10:26 PM UTC
There is an Application.Idle event handler in the GridGroupingControl. Your event handler and the grid''s event handler may be fighting each other.
Exactly what forum thread discusses why you are trying to use record.SetCurrent in Idle? Maybe there is another way to get this record.SetCurrent to be done without trying to use the Idle event?
AD
Administrator
Syncfusion Team
November 29, 2005 10:50 AM UTC
I have tried to move the SetCurrent call out of the Application.Idle event, but this doesn''t help. Also, I am not calling SetCurrent when the infinite loop is running. I do have an application.idle handler, but when the infinite loop is running, my handler does no work (only checks a status variable and then returns).
However, it seems that the fact that I have called SetCurrent, previously in the program is a necessary condition to trigger the infinite loop.
Also, it seems that the thing triggering the loop is that my application.idle handler once does a fairly length computation. However, it does not repeat this computation after the loop in the grid has been triggered.
I am really appreciating your help on this.
BTW the reason for calling SetCurrent is discussed here
http://www.syncfusion.com/Support/Forums/message.aspx?MessageID=30347
AD
Administrator
Syncfusion Team
November 29, 2005 02:01 PM UTC
Do you have our source code? If so, you could use a debug build of our libraries, and then when things lock up, you could do break, and check the call stack. You could then continue the excution for awhile, and then retry the the break to see if it is still in the same loop. Getting this call stack may point to what is causing this problem.
AD
Administrator
Syncfusion Team
December 1, 2005 09:35 AM UTC
Yes, I have the source. When the cpu was running at 100% I randomly breaked several times. The call stacks are shown below. I have noticed that the method GridTableControl.SynchronizeGridWithEngine seems to have been called every time, and some of the times the Application.Idle handler GridTableControl.Application_Idle has been called. But apart from that it is difficult for me to understand what is going on. Does this help you to pinpoint the problem?
P.S. Sorry for the long text. Feel free to delete this afterwards.
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridColumnDescriptorCollection.EnsureInitialized(bool populate = true) + 0x123 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridColumnDescriptorCollection.get_Version() + 0x13 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableDescriptor.EnsureSummaryDescriptors() + 0x92 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.SynchronizeGridWithEngine() + 0x151 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.Application_Idle(System.Object sender = {System.Threading.Thread}, System.EventArgs e = {System.EventArgs}) + 0x67 bytes
system.windows.forms.dll!ThreadContext.System.Windows.Forms.UnsafeNativeMethods+IMsoComponent.FDoIdle(int grfidlef = -1) + 0x33 bytes
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(int dwComponentID = 22, int reason = -1, int pvLoopData = 0) + 0x3f2 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x50 bytes
system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm = {Sigma.Matrics.Forms.FormMain}) + 0x34 bytes
> Matrics.exe!Sigma.Matrics.Forms.FormMain.Main(string[] args = {Length=0}) Line 1952 C#
syncfusion.grouping.base.dll!Syncfusion.Grouping.TableCollection.SynchronizeWithRelationDescriptor() + 0x13 bytes
syncfusion.grouping.base.dll!Syncfusion.Grouping.TableCollection.get_Count() + 0x10 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTable.GetHorizontalScrollWidth(bool isNested = false) + 0x9a bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTable.GetHorizontalScrollWidth() + 0x12 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.GetHorizontalScrollWidth() + 0x21 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.SynchronizeGridWithEngine() + 0x16f bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.OnBeforePaint(System.EventArgs e = {System.EventArgs}) + 0x56 bytes
syncfusion.grid.windows.dll!Syncfusion.Windows.Forms.Grid.GridControlBase.WndProc(System.Windows.Forms.Message msg = {System.Windows.Forms.Message}) + 0x120 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.WndProc(System.Windows.Forms.Message msg = {System.Windows.Forms.Message}) + 0xea bytes
system.windows.forms.dll!ControlNativeWindow.OnMessage(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x13 bytes
system.windows.forms.dll!ControlNativeWindow.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0xda bytes
system.windows.forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(int hWnd = 67512, int msg = 15, int wparam = 0, int lparam = 0) + 0x3d bytes
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(int dwComponentID = 22, int reason = -1, int pvLoopData = 0) + 0x349 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x50 bytes
system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm = {Sigma.Matrics.Forms.FormMain}) + 0x34 bytes
> Matrics.exe!Sigma.Matrics.Forms.FormMain.Main(string[] args = {Length=0}) Line 1952 C#
syncfusion.grouping.base.dll!Syncfusion.Grouping.FieldDescriptorCollection.get_Version() + 0x13 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridColumnDescriptorCollection.EnsureInitialized(bool populate = true) + 0x14d bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridColumnDescriptorCollection.get_Version() + 0x13 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridVisibleColumnDescriptorCollection.EnsureInitialized(bool populate = true) + 0xf6 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridVisibleColumnDescriptorCollection.get_Version() + 0x13 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableDescriptor.EnsureRecordRowColumns() + 0x9f bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.SynchronizeGridWithEngine() + 0x166 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.OnBeforePaint(System.EventArgs e = {System.EventArgs}) + 0x56 bytes
syncfusion.grid.windows.dll!Syncfusion.Windows.Forms.Grid.GridControlBase.WndProc(System.Windows.Forms.Message msg = {System.Windows.Forms.Message}) + 0x120 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.WndProc(System.Windows.Forms.Message msg = {System.Windows.Forms.Message}) + 0xea bytes
system.windows.forms.dll!ControlNativeWindow.OnMessage(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x13 bytes
system.windows.forms.dll!ControlNativeWindow.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0xda bytes
system.windows.forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(int hWnd = 67512, int msg = 15, int wparam = 0, int lparam = 0) + 0x3d bytes
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(int dwComponentID = 22, int reason = -1, int pvLoopData = 0) + 0x349 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x50 bytes
system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm = {Sigma.Matrics.Forms.FormMain}) + 0x34 bytes
> Matrics.exe!Sigma.Matrics.Forms.FormMain.Main(string[] args = {Length=0}) Line 1952 C#
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.get_ParentDesignMode() + 0x36 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.WndProc(System.Windows.Forms.Message msg = {System.Windows.Forms.Message}) + 0x34 bytes
system.windows.forms.dll!ControlNativeWindow.OnMessage(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x13 bytes
system.windows.forms.dll!ControlNativeWindow.WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0xda bytes
system.windows.forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(int hWnd = 67512, int msg = 15, int wparam = 0, int lparam = 0) + 0x3d bytes
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(int dwComponentID = 22, int reason = -1, int pvLoopData = 0) + 0x349 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x50 bytes
system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm = {Sigma.Matrics.Forms.FormMain}) + 0x34 bytes
> Matrics.exe!Sigma.Matrics.Forms.FormMain.Main(string[] args = {Length=0}) Line 1952 C#
syncfusion.grouping.base.dll!Syncfusion.Grouping.RelationDescriptorCollection.get_Version() + 0x14 bytes
syncfusion.grouping.base.dll!Syncfusion.Grouping.FieldDescriptorCollection.EnsureInitialized(bool populate = true) + 0x1e0 bytes
syncfusion.grouping.base.dll!Syncfusion.Grouping.FieldDescriptorCollection.get_Version() + 0x13 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridColumnDescriptorCollection.EnsureInitialized(bool populate = true) + 0x14d bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridColumnDescriptorCollection.get_Version() + 0x13 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableDescriptor.EnsureSummaryDescriptors() + 0x92 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.SynchronizeGridWithEngine() + 0x151 bytes
syncfusion.grid.grouping.windows.dll!Syncfusion.Windows.Forms.Grid.Grouping.GridTableControl.Application_Idle(System.Object sender = {System.Threading.Thread}, System.EventArgs e = {System.EventArgs}) + 0x67 bytes
system.windows.forms.dll!ThreadContext.System.Windows.Forms.UnsafeNativeMethods+IMsoComponent.FDoIdle(int grfidlef = -1) + 0x33 bytes
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(int dwComponentID = 22, int reason = -1, int pvLoopData = 0) + 0x3f2 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x50 bytes
system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm = {Sigma.Matrics.Forms.FormMain}) + 0x34 bytes
> Matrics.exe!Sigma.Matrics.Forms.FormMain.Main(string[] args = {Length=0}) Line 1952 C#
AD
Administrator
Syncfusion Team
December 8, 2005 09:04 AM UTC
Do you have any more ideas about the cause of this problem?
AD
Administrator
Syncfusion Team
December 8, 2005 09:30 AM UTC
Kjetil,
in your Idle code do you access the engine, or make changes to it? If yes, what is the code look that accesses the engine?
The call stacks you have indicate that a change was made to the engine and it tries to synchronize itself with latest changes.
Stefan
AD
Administrator
Syncfusion Team
December 8, 2005 11:43 AM UTC
Hi Stefan.
After the loop has started my Idle code does nothing (only checks a status variable and returns). Before (or at the start?) of the loop, my Idle code access the grid by calling the method gridRecord.SetCurrent().
AD
Administrator
Syncfusion Team
December 8, 2005 02:14 PM UTC
Kjetil,
try this:
Instead of directly calling SetCurrent, call SetCurrent from a Timer event after the Idle processsing:
private void t_Tick(object sender, EventArgs e)
{
Timer t = (Timer) sender;
t.Tick -= new EventHandler(t_Tick);
t.Stop();
t.Dispose();
// Place SetCurrent call here, e.g.
if (!record.IsCurrent())
record.SetCurrent();
}
Timer t = new Timer();
t.Interval = 10;
t.Tick += new EventHandler(t_Tick);
t.Start();
Does this help?
How often is SetCurrent being hit?
Another thing to check out:
If SetCurrent still keeps giving problems try calling grid.TableControl.CurrentCell.MoveTo(grid.Table.DisplayElements.IndexOf(record));
instead of record.SetCurrent
Stefan
>Hi Stefan.
>
>After the loop has started my Idle code does nothing (only checks a status variable and returns). Before (or at the start?) of the loop, my Idle code access the grid by calling the method gridRecord.SetCurrent().
>
AD
Administrator
Syncfusion Team
December 8, 2005 03:34 PM UTC
Unfourtunately, none of these approaches worked.
With the first one, I still got into the infinite loop.
The second had the same problem as the reason why I want to call SetCurrent() in the first place: It doesn''t always open closed groups.
I think I am close to giving up on this one!
AD
Administrator
Syncfusion Team
December 8, 2005 03:40 PM UTC
P.S. SetCurrent() is only called a few times before the loop starts and never after.
AD
Administrator
Syncfusion Team
December 9, 2005 05:23 AM UTC
It''s hard to give suggestion without a sample project. So it''s just shots in the dark ...
One more thing to try: Does calling Table.ShowRecord(r) instead of r.SetCurrent() make a diffrerence?
Stefan
>P.S. SetCurrent() is only called a few times before the loop starts and never after.