We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy.
Unfortunately, activation email could not send to your email. Please try again.

Grid checkboxes get exceptions in multi-GUI thread process

Thread ID:

Created:

Updated:

Platform:

Replies:

28722 May 9,2005 12:06 PM May 19,2005 11:06 AM Windows Forms 19
loading
Tags: GridControl
Bruce Davis
Asked On May 9, 2005 12:06 PM

[Using 2.1.0.9] I have an application that creates a separate GUI thread for each of its main windows. Each main window has a "launchpad" user control containing a GDBG. The second column in the GDBG is configured to display as a checkbox. When I run this application with only one window up, everything works fine. When I launch a second window (and hence a second GUI thread), the launchpad''s grid''s checkboxes sometimes turn red and display the word "Exception". I find that the exception occurs when both grids are refreshing at the same time. Down in the depths of the error, the grid reports that "The object is in use elsewhere", though I haven''t a clue what object it''s complaining about (likely an internal detail). Short of making my app a single-GUI thread app, is there anything I can do to keep these exceptions from occurring?

Bruce Davis
Replied On May 9, 2005 12:39 PM

Here''s the exception: A first chance exception of type ''System.InvalidOperationException'' occurred in system.drawing.dll Additional information: The object is currently in use elsewhere. catched at Syncfusion.Windows.Forms.Grid.GridControlBase.OnDrawItem(Graphics g, Int32 rowIndex, Int32 colIndex, Rectangle rectItem, GridStyleInfo style) in :line 0

Administrator [Syncfusion]
Replied On May 9, 2005 12:51 PM

You can only interact with a Windows Forms control (including our grids) on the thread that created it. So, anytime you try to access a method on one of teh grids, are you checking grid.InvokeRequired to see if you need to invoke a delagate call on theh grid''s thread to make sure you access teh grid on the proper thread? Not doing this will cause problems such as you described. Here is a kb link discussing using threads. http://www.syncfusion.com/Support/article.aspx?id=572 If this is not what you are seeing, then if you can upload a sample project showing this problem, we can debug it here to see what might be going on. (You might try hiding/removing the checkbox to see if that really is what is triggerring this problem??)

Bruce Davis
Replied On May 9, 2005 01:09 PM

We are following all of the basic laws of multi-threaded GUI programming, so we''re checking InvokeRequired and Invoking/BeginInvoking where we need to. In this case, the impetus for the refresh comes from a worker thread, so we''re marshalling to the correct GUI thread before interacting with the grid. If it helps, we never see the problem for any other grid cell type -- only checkboxes. I''ll work on getting a boiled down sample app to you.

Administrator [Syncfusion]
Replied On May 9, 2005 01:17 PM

Just something else to check. Are you using themed checkboxes? If so, try turning off themes (grid.ThemesEnabled = flase) to see if that is playing a role in this problem.

Bruce Davis
Replied On May 9, 2005 01:43 PM

We have themes turned off on all of our grids, so we can eliminate that variable.

Ramya Modukuri
Replied On May 17, 2005 10:56 AM

Continuing where Bruce left off... Here''s a sample application to reproduce the problem. It occurs a lot more frequently on dual processor machines (which is what our clients use), so please be sure to run this on one. When the application runs, click on the Launch menu to bring up another form (or two). All forms refresh every one second. The checkbox column on the left will turn red frequently and show the word "Exception". It might take a few minutes for the problem to show up. CheckboxTest_252.zip

Administrator [Syncfusion]
Replied On May 17, 2005 02:13 PM

I will not have access to dual processor systems until tomorrow so I shoul dbe able to try out your code then. But looking through your code, does changing _grid.DataSource = _model.Data; to _grid.DataSource = new DataView(_model.Data); make any difference?

Ramya Modukuri
Replied On May 17, 2005 03:37 PM

No, it doesn''t.

Administrator [Syncfusion]
Replied On May 18, 2005 05:31 AM

I changed your delegate _model_dataChanged to test to see whether you were accessing the gird on some thread other than the one that created it using this code.
private void _model_DataChanged(object sender, EventArgs e)
{     
     if(!this.IsDisposed)
     {
	if(_grid.InvokeRequired)
		throw new Exception("not the grid''s thread");
        _grid.Refresh();
     }
}
When I did this, I immediately saw not the grid thread exception being thrown. I then changed your code to read:
private void _model_DataChanged(object sender, EventArgs e)
{
	if(!this.IsDisposed)
	{
		if(_grid.InvokeRequired)
			_grid.Invoke(new EventHandler(_model_DataChanged));
		_grid.Refresh();
	}
}
After this, the grid code was being done on the proper thread. A couple of other exceptions were hit as the sencond grid was being initialized, but I think these were caused by the stop you had set during initialization. When I removed the stop, the exceptions I saw went awayand there were no red cells in either grid.

Administrator [Syncfusion]
Replied On May 18, 2005 05:34 AM

One othe rnote. The dual precessor system I used had version 3.2.1 installed on it, so I did not use your 2.1.0.9. But hopefully, adding the proper InvokeRequired checks will handle the problem similarly in the 2.1.0.9 sample you sent.

Ramya Modukuri
Replied On May 18, 2005 09:54 AM

Sorry, my fault. The code should''ve read: if(!this.IsDisposed) { if(InvokeRequired) { Invoke(new EventHandle(_model_DataChanged)); return; // this was absent in the sample } _grid.Refresh(); } Leaving out the "return" was causing the non-gui thread to call _grid.Refresh after returning from the Invoke call. So now, if you break on _grid.Refresh, and look at the Threads, it''ll show the call being executed on the correct thread. However, running this on a dual proc will still give you this : A first chance exception of type ''System.InvalidOperationException'' occurred in system.drawing.dll Additional information: The object is currently in use elsewhere. catched at Syncfusion.Windows.Forms.Grid.GridControlBase.OnDrawItem(Graphics g, Int32 rowIndex, Int32 colIndex, Rectangle rectItem, GridStyleInfo style) in :line 0

Administrator [Syncfusion]
Replied On May 18, 2005 10:02 AM

With the change you suggested, I can launch several grids on a dual processor system using 3.2.1.0 without getting any exceptions or red cells. Later today, I will install 2.1.0.9 on that system to see it things break with that version. Have you tried it using our latest code?

Ramya Modukuri
Replied On May 18, 2005 10:14 AM

You mean version 3.2.1.0?

Administrator [Syncfusion]
Replied On May 18, 2005 10:26 AM

The sample you sent was licensed for 2.1.0.9 and has those references, so I thought you were using 2.1.0.9. The dual processor system where I see it work without a problem used 3.2.1.0. All I do after changing the references and setting up the licensing is to do a ctl+F5 and launch several of teh grids. The checkboxes come up ok for me. What version are you using?

Ramya Modukuri
Replied On May 18, 2005 10:38 AM

I''m using 2.1.0.9. When you asked me if I had tried it using our latest code, I wasn''t sure which version you were referring to, which is why I asked if the 3.x version is the latest. I haven''t tried it with 3.2.1.0.

Administrator [Syncfusion]
Replied On May 18, 2005 02:12 PM

I installed 2109 on that dual processor system. Using that release, I still did not see any red checkboxes, but I could reliably get an ''object in use'' exception by dragging grids over each other. Sometimes it took a while, but it would happen. I could not see this behavior in 3.2.1.0. But still no red checkboxes.

Ramya Modukuri
Replied On May 18, 2005 03:13 PM

Can you please try it in non-debug mode (running the exe) with more than 2 windows? Maybe setting the timer to a smaller interval would also work. If that doesn''t work, I''ll try to send a better sample. Our actual application is, obviously, a lot more complex and we see this problem once every few seconds. It''s defitely related to the exception you''re seeing. Thanks.

Administrator [Syncfusion]
Replied On May 19, 2005 08:03 AM

Speeding up the time, did let me see the red checkboxes in 2109. The exceptions are being raised in a call to the .NET framework''s ControlPaint.DrawCheckBox. We use this call to draw the non-themed checkboxes. It looks like this ControlPaint.DrawCheckBox is not thread safe. If I replace the ControlPaint.DrawCheckBox call with a direct calls to Graphics.FillRectangle to draw red or green squares for the true or false checks, then problem goes away. So, one solution is for us to remove the dependence on ControlPaint.DrawCheckBox, and draw the checkboxes ourselves, making sure we do this is a thread safe manner. We will try this solution for future releases, but to use it in 2.1.0.9 would require you to derive the checkbox dell type and override teh renderer''s DrawCheckBox method and draw the checkbox without using ControlPaint.DrawCheckBox.

Robin Duerden
Replied On May 19, 2005 11:06 AM

The problem is that the datagrid is attaching to the datatables'' change events directly (as can be seen by removing the _model_DataChanged handler from the testform.cs and still seeing changes in the grid), and that these events are being raised from a different thread than the grid was created from. From memory, 2.1.0.9''s databound grid did not use ''InvokeRequired'' on responding to datasource changes where as 3.x does.

CONFIRMATION

This post will be permanently deleted. Are you sure you want to continue?

Sorry, An error occured while processing your request. Please try again later.

You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.

;