?
Solved

Need debugging help for InvalidOperationException

Posted on 2005-03-28
9
Medium Priority
?
503 Views
Last Modified: 2012-06-27
I have a program that I have simplified, but still I am getting an intermitiant crash with a NullPointer Exception.  

I have a user control derived class that displays a changing bitmap.  In the class, I have implemented a timer using System.Timers.Timer and in the Elapsed event, I call the Refresh method on the UserControl.  In the paint delegate defined on the class, I check to see if the bitmap data member of the class is null or not.  If not, I call the passed in PaintEventArgs Graphics object DrawImage method to draw the bitmap.

 But for some reason, I eventually get a NullPointerException in the DrawImage call and when I examine the bitmap and graphics objects, I see in the Quick Watch panel the value of InvalidOperationException.  I have checked the threads running and I have checked my dispose method and I am sure the object with the paint delegate being invoked is a valid object and the bitmap was just set on the object.  I even tried cloning the bitmap to be sure it is a "fresh" one so it will not get deleted out from under me.

I am at my wits end to figure out how to determine what is wrong.  I dont know what else to do to figure out why the bitmap is becoming invalid.  Can anyone tell me what might be going wrong and how I can fix it?

Is there a problem with running a worker thread and calling the Refresh method on myself?

Is there a way I can tell if the Graphics object is invalid?  Its not null, but it is also not valid?  How can I trace what caused the class to get into the broken state it seems to be in?  

I put in a global unhandled exception hander and if I run the program outside of the debugger, I get the following exception:

The object is currently in use elsewhere.

System.InvalidOperationException

Stack Trace:
   at System.Drawing.Graphics.EndContainer(GraphicsContainer container)
   at System.Windows.Forms.DibGraphicsBufferManager.ReleaseBuffer(GraphicsBuffer buffer)
   at System.Windows.Forms.GraphicsBuffer.Dispose()
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ContainerControl.WndProc(Message& m)
   at System.Windows.Forms.UserControl.WndProc(Message& m)
   at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

I dont understand why this is happening or how to narrow down what is the cause.  There are no methods in my code involved with this error.  Can someone clearify what this means?

Thanks
Bryan
0
Comment
Question by:bryanwells
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
9 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 13652944
Do you keep a module-level reference to the Graphics object, or do you get a reference to it on every call?

Bob
0
 

Author Comment

by:bryanwells
ID: 13655854
I use the graphics object passed in to a paint method as a data member of the PaintEventArgs.  I dont think I am holding on to any graphics objects anywhere.  
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 13655906
Invalid operation with GDI+ is usually based on not having the proper Graphics object.  Since you have a confusion created by using threading, it will be tough to isolate the cause.  I am not sure that I can help you with this fairly complex problem.

Bob
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:bryanwells
ID: 13656338
I did some poking around on some other forums and found others had this same stack trace and it was suggested a bug in .NET involving double buffering.  Indeed, i am setting the following styles on my user control:

this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  this.SetStyle(ControlStyles.DoubleBuffer, true);
  this.SetStyle(ControlStyles.UserPaint, true);
 
I will try "NOT" setting the double buffer style and see what happens.  Can anyone say something about this possiblity that double buffering might be a problem?

thanks
Bryan
0
 

Author Comment

by:bryanwells
ID: 13656646
Just another note.  The problem I have described happens when I delete one instance of my user control and create another instance of the same control.  Its in the second instance that the problem shows up.  If I never delete and re-create, I dont see the problem.  Cleary, this points to a dispose-object issue, but I am very sure I am not hanging on to anything.  I simply create, use and then dispose.  And re-create.  When I dispose of the object, I stop the timer.  

I have put an ID into my objects, and i can confirm the ID of the one that gets the crash is always the second object created. I never get a paint call on the disposed object.  Perhaps the double buffering is hanging onto a graphics object after my dispose has been called.
0
 

Author Comment

by:bryanwells
ID: 13660644
I removed the automatic double buffering and now I get the following stack trace:

Unhandled Exception:

The object is currently in use elsewhere.

System.InvalidOperationException

Stack Trace:
   at System.Drawing.Graphics.Dispose(Boolean disposing)
   at System.Drawing.Graphics.Dispose()
   at System.Windows.Forms.PaintEventArgs.Dispose(Boolean disposing)
   at System.Windows.Forms.Control.WmPaint(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ContainerControl.WndProc(Message& m)
   at System.Windows.Forms.UserControl.WndProc(Message& m)
   at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 1000 total points
ID: 13661307
Possible cause:

http://www.error-bank.com/microsoft.public.dotnet.languages.csharp/269266_Thread.aspx

Comment:
One possible cause for the "The object is currently in use elsewhere"
problem is if you access UI elements (forms or other controls) from non-UI
threads. If you are using multi-threaded code, then I'd double check it. One
way to do this is to put this assert as the first line of methods in your UI
classes:

   System.Diagnostics.Debug.Assert(!this.InvokeRequired, "InvokeRequired");

Then run your application and if you hit the assert, you know you've got a
threading problem. Or, if you don't hit the assert, then at least you've
ruled out this potential problem.

Bob
0
 

Author Comment

by:bryanwells
ID: 13661664
Do you consider calling Refresh from a non-UI thread to be the case you describe?  Or does calling Refresh put the call on the main thread correctly?

Thanks
Bryan
0
 

Author Comment

by:bryanwells
ID: 13666195
I read your suggestion and it appears I might not be able to call a user control constructor from a worker thread.  Is this the case?  I know in one case I am calling a constructor from a delegate that is responding to a use mouse event.  I will try the InvokeRequired test to see what that does.  It seems that calling a form's consructor from a delegate called from a  mouse event delegatate would be safe.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question