Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- From: "Bob Powell [MVP]" <bob@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Mon, 20 Jun 2005 20:05:50 +0200
I have written code to stress the system and have not found any indication
that lots of use causes the error. Some applications just refuse to run
using built-in double buffering, others never show an exception after
literally weeks of soak-testing.
In order to post a bug I need to make it reproducable otherwise MS will not
pay it much attention.
--
Bob Powell [MVP]
Visual C#, System.Drawing
Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm
Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm
All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
"Garry Freemyer" <garryfre@xxxxxxxxxxxxxxxxxxx> wrote in message
news:uqHfbhadFHA.3712@xxxxxxxxxxxxxxxxxxxxxxx
> Well, I suppose the way to nail it down would be to create a small version
> of this that just does a whole lot of grapics, I mean really stress the
> double-buffering, and show that it fails, or feel free to pack up my code
> to the screensaver and send it to them, there is a config option, where I
> chose auto-double buffering or manual buffering, and the first works, the
> second breaks horribly.
>
> By the way, InvalidOperationException, is NOT caught by a catch
> InvalidOperationException at all and those catches that do catch it have
> the exception stolen from them by the runtime. It's snatched away from
> their program by the runtime, which to me is a terrible thing to do to a
> programmer. I can only PARTIALLY catch it with a regular empty catch that
> I know I know it caught the error because the showcursor is executed, but
> the rest fails to execute because after the first line in the catch
> statement is execute and before the next line, the runtime kidnaps my
> error handling by somehow taking control away and putting up that cursed
> dialog box. Really, I see no excuse for a runtime kidnapping my code
> execution and fingering my code as if I did not write an exception handler
> at all - a cardinal sin of programming.
>
> It would only take a program that really stresses the system and
> demonstrates it in three modes ...
>
> 1. Double-buffering showing the breakage, the kidnapping of the error
> handler execution.
> 2. Auto Double Buffering showing that the program works. These two my
> program can do.
> 3. Showing how using flat 32 unmanaged code that gives ME control over
> when the backbuffer is drawn to the screen and when it's released solves
> the problem.
>
> The fact that GDI+ take away my ability to control when the backbuffer is
> applied, ought to be proof enough that the GDI isn't so much as broken,
> but is merely missing a vital piece of functionality. There is also the
> proof in the documentation itself that either the documentation is wrong
> or GDI+ stands for blank blank irritating and I bet you can guess what the
> first two words are.
>
> The closest to controlling when the backbuffer is written appears to be
> the flush command, but it contains all EXCEPT what I need because of the
> missing feature ...
>
> 1. Flush which strangely tells the system to start to write the
> backbuffer, BUT does so assynchroneously and yet says the command syncs
> the graphics objects?!!?? What is syncroneous about an assync operation?
> What This sets the program up for a blunder right then and there because
> then all I need is three with lines with auto buffering on...
>
> pev.Graphics.DrawSomethingbig(); // Draw something that will take a long
> time to draw.
> pev.Graphics.Flush(FlushIntention.Flush); // Start the drawing from the
> backbuffer to the screen...
> pev.Graphics.DrawAnything(); // Cause the InvalidOperationException error
> by trying to draw to the backbuffer while it is in an innaccessible state
> because it is being read or closing.
>
> 2. The Sync option, which the documentation says causes the program to
> wait till the flush is done before returning and then the docs turn around
> and says it "Syncs all graphics objects". Why would I be having more than
> ONE graphics object ultimately referring to the same buffer?? That would
> be like having a car where there are two drivers going to the same
> destination, but trying to take different routes? The docs are confusing
> at best, vague in the very least. My guess on this was that it is a
> write-now operation despite that it say to write as soon as possible
> implying that the command is assync!
>
> 3. What is missing is a method to tell the double-buffering NOT to write
> till I issue a flush command, otherwise, its guess work, on the part of
> GDI+ that is going to end up tripping over it's own feet.
>
> I suppose the GDI+ Auto-Double buffer could be considered broken and
> broken badly if it was intended that it would check first before trying to
> access the backbuffer for writing or reading while it's busy being read,
> or written or worse yet, being disposed, but then that begs the question
> about why would Migrosoft presume to imagine that all the diverse graphic
> needs could all be shoehorned into a narrow minded double buffering model
> that gives the programmer NO control over when the backbuffer is drawn.
> It's like a car with a huge accelleration pedel, but no brakes - It's
> going to crash!!
>
> I've been working on this saver, for weeks, I've seen this error about 80
> times, despite the fact that it can take up to 10 hours for it to show! It
> is exasperating in the extreme. I feel like I've spent half a million
> dollars putting together a custom built Citrine Mazaradi, and I am sitting
> in the garage all gassed up, polished up, in the driver seat ready to go
> the door is open, but I can't exit the garage because a piece of sand is
> in the way! Doh!
>
>
>
> 1. Running auto-double buffering, and get the error, which
> "Bob Powell [MVP]" <bob@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
> news:ej1MlwZdFHA.2420@xxxxxxxxxxxxxxxxxxxxxxx
>> This is interesting because I've suspected for some time that double
>> buffering is broken and I've seen exceptions due to the use of automatic
>> double buffering on several occasions. It would be great to nail this
>> down and post it as a real bug report with MS.
>>
>> --
>> Bob Powell [MVP]
>> Visual C#, System.Drawing
>>
>> Find great Windows Forms articles in Windows Forms Tips and Tricks
>> http://www.bobpowell.net/tipstricks.htm
>>
>> Answer those GDI+ questions with the GDI+ FAQ
>> http://www.bobpowell.net/faqmain.htm
>>
>> All new articles provide code in C# and VB.NET.
>> Subscribe to the RSS feeds provided and never miss a new article.
>>
>>
>>
>>
>>
>> "Garry Freemyer" <garryfre@xxxxxxxxxxxxxxxxxxx> wrote in message
>> news:uS1UbjWdFHA.3808@xxxxxxxxxxxxxxxxxxxxxxx
>>> Here is some of the points and observations about my screensaver, where
>>> I am being tortured by the InvalidOperationException raised from
>>> System.Graphics.EndContainer(). Here is what I think is happening. Does
>>> the stack trace below bear this out? Is there a method to tell the
>>> control when to copy it's backbuffer to the screen, and when NOT to, but
>>> to wait?
>>>
>>> 1. The manual double buffering never crashes. In this kind of buffering
>>> there is no double buffer between the graphics object, and the display,
>>> and so there is no guess work about when the drawn lines and Images that
>>> are loaded and displayed because they are loaded when the paint event
>>> argument is told to load the image, it displays it right away.
>>>
>>> 2. I noticed that even tho I specify a particular swarm to appear on
>>> screen, instead of appearing within seconds of each other because the
>>> drawing is fast. So, things drawn are not displayed immediately when
>>> using the SetStyle DoubleBuffer, true);
>>>
>>> 3. The contol's built in double buffering is automatic in that the
>>> control has a backbuffer, that you have little control over! In this
>>> scenario the control has to guess when it's time to copy the backbuffer
>>> to the display and also guess when it's time to clear it's backbuffer
>>> and the only metric it has, is a couple of hints in the flush method,
>>> and the next slot of idle time.
>>>
>>> So, that's it!! The control under double-buffering via the setstyle is
>>> deciding to flush the buffer out to the screen just before my program
>>> tries to start drawing to it! The control tries to end container on the
>>> bitmap, but the bitmap is still being drawn to!
>>>
>>> This would explain the delaytime where I have seven swarms on the
>>> screen, but one only appears every 4 seconds, till they are all
>>> on-screen.
>>>
>>> If this is raising an event, that eventually turns into a paint event,
>>> then, the thread could be blocking itself by invoking threads.
>>>
>>> So, the event is being caused by the bad guesswork about when a buffer
>>> is to be drawn and disposed of! In every error there is this message
>>> about something trying to access the buffer while it's being disposed!
>>>
>>> Since this drawing is so fast, it also explains why it can take hours
>>> for the exception to show its ugly face because the program is like a
>>> slightly drunken person tripping over it's own feet!
>>>
>>> I'm a bit surprised that there aren't or that I've not found in any
>>> double-buffering articles, a command to tell the graphic to stop
>>> guessing around and copy and dispose of the backbuffer when I tell it
>>> that it's time to.
>>>
>>> Here is the trace ...
>>>
>>> See the end of this message for details on invoking
>>> just-in-time (JIT) debugging instead of this dialog box.
>>>
>>> ************** Exception Text **************
>>> System.InvalidOperationException: The object is currently in use
>>> elsewhere.
>>> 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.Form.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)
>>>
>>>
>>>
>>> --
>>> To reply to this message take off the .NoJunkSpam off of the end of
>>> garryfre@xxxxxxxxxxxxxxxxxxxxxx
>>>
>>
>>
>
>
.
- Follow-Ups:
- Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- From: Garry Freemyer
- Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- From: Garry Freemyer
- Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- References:
- I think I know why setstyle double buffering cases invalidOperationExceptions!
- From: Garry Freemyer
- Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- From: Bob Powell [MVP]
- Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- From: Garry Freemyer
- I think I know why setstyle double buffering cases invalidOperationExceptions!
- Prev by Date: Re: DrawTrackerRect?
- Next by Date: Re: DrawTrackerRect?
- Previous by thread: Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- Next by thread: Re: I think I know why setstyle double buffering cases invalidOperationExceptions!
- Index(es):
Relevant Pages
|
Loading