.NET Framework - Vista X64 GDI+ and System.Drawing errors

Asked By dale097
04-Nov-07 08:06 PM
I have an application that I have used for years on 32-bit XP.  It also
appears to run properly on 32-bit Vista - at least I haven't had any users
complain.

When I try to run the app on Vista X64, I get errors randomly in
System.Drawing and GDI+ when I call Image.FromStream(Stream).

If the System.Drawing exception occurs, it is an ArgumentException and the
message is "Parameter is not valid."  The stack trace provides this
information:

at System.Drawing.Image.FromStream(Stream stream, Boolean
useEmbeddedColorManagement, Boolean validateImageData)\r\n   at
System.Drawing.Image.FromStream(Stream stream)

It appears to be an internal error in System.Drawing - or GDI+ that
System.Drawing is not passing on unchanged so I can't tell.

If the GDI+ error occurs, the exception is of type
System.Runtime.InteropServices.ExternalException.  The error message says "A
generic error occurred in GDI+."  The stack trace shows the same message as
above for the System.Drawing exception.

I get either one or the other, I don't get both in the same instance.

I create a MemoryStream in a BackgroundWorker thread with this code:

MemoryStream imageStream = null;

if (files.Length > 0 && File.Exists(picturePath))
{
imageStream = GetImageStream(picturePath);
}


That stream is passed to the BackgroundWorker's ProgressChanged event as a
property of a custom class passed in the UserState object of the
ProgressChangedEventArgs and converted to an image with:

Image mg = null;

try
{
mg = Image.FromStream(p.PictureData);
}
catch(Exception ex)
{
MessageBox.Show("Cannot create image for " +
p.Mp3FileName + "\r\n" + "Exception: " + ex.Message);
}


where p is the object instance that I passed in UserData.

A strange thing is that if I set a break point on the catch block and when
the break occurs I run:

mg = Image.FromStream(p.PictureData);

from the Immediate Window, the call is successful and mg will hold the
expected image.  That tells me that the problem is not in the image data
itself.

Please keep in mind that this does only happen in Vista X64, not in Vista X86.

Thanks in advance for any help with this.

Dale

--
Dale Preston
MCAD C#
MCSE, MCDBA
System.Drawing.Image.FromStream
(1)
ProgressChangedEventArgs
(1)
Vista
(1)
ExternalException
(1)
ArgumentException
(1)
BackgroundWorker
(1)
Image.FromStream
(1)
MemoryStream
(1)
  dale097 replied...
04-Nov-07 08:22 PM
By the way, this is a .Net 2.0 application.
--
Dale Preston
MCAD C#
MCSE, MCDBA
  Peter Duniho replied...
04-Nov-07 09:12 PM
On 2007-11-04 17:06:02 -0800, Dale <dale0973@nospam.nospam> said:


Well, it tells you that the problem is not in the image data >>> at the
time you enter the statement in the Immediate Window <<<.  It tells you
nothing about the stream prior to that point.

You haven't posted a concise-but-complete sample of code for us to look
at.  But the behavior you're describing sounds a lot like a race
condition.  It could be related to the reading of the file and creation
of the memory stream, or in how you set the value used in the
ProgressChanged event, or it might not be a bug in your code at all
(though bugs in one's own code are MUCH more likely than bugs in .NET,
the latter is not impossible).  Without seeing a complete sample of
code, it's not possible to say.

Pete
  dale097 replied...
05-Nov-07 12:15 AM
While you may be correct that p.PictureData is not legitimate in the try and
is legitimate in the catch, I don't see how that can happen.  The
BackgroundWorker does not use the the instance of the object for p after
calling ReportProgress.  I can't find any other alternate thread references
to the stream that would exist to indicate that a missing value would have
been updated in p in between.

In the BackgroundWorker code, ReportProgress would never be called if the
stream was not initialized.

Here is the code that initializes the stream:

First, I make sure the source image file exists:

if (File.Exists(picturePath))
{
imageStream = GetImageStream(picturePath);
}

Then I fill imageStream with the image by assigning the return value from
this code:

FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read,
FileShare.Read);
MemoryStream ms = new MemoryStream((int)fs.Length);

const int size = 4096;
byte[] bytes = new byte[4096];
int numBytes;
while ((numBytes = fs.Read(bytes, 0, size)) > 0)
ms.Write(bytes, 0, numBytes);

fs.Close();
fs.Dispose();

return ms;

Then I make sure that imageStream is not null and that it has something in
it with this code I just put in for troubleshooting.  The if statement never
matches; the exception never gets thrown:

if (imageStream == null || imageStream.Length < 10000)
{
throw new Exception("Bad imageStream!!!");
}

And next comes a loop that uses the same stream several times including
calling ReportProgress where the exception occurs in the handler.  In this
loop, some iterations will work and some will not.  This pretty much proves
that the stream is valid since iteration 1 may work, 2 may not, maybe 3
through 6 will work, 7 will not, etc.


for (int count = 0; count < files.Length; count++)
{
ProcessImage(imageStream);
imagesProcessedCount++;

backgroundWorker1.ReportProgress(CalculatePercentComplete(fileCount,
imagesProcessedCount), new PictureProgress(
startingFolder,
imageFileName,
files[count],
fileCount,
imagesProcessedCount,
imageStream));
}



Because of the size and complexity of the application, recreating this bug
in code that could be posted here would be virtually impossible.

I guess I am hoping someone would have run across a similar roblem with GDI+
or System.Drawing in Vista X64, or with BackgroundWorker in Vista X64.

I don't know if it has any bearing or not, but if it is a race condition,
perhaps the fact that I have Vista X64 running on a dual quad-core Xeon
system and all the machines I run it on are single-core machines.  I have had
quite a few people download the application from my site and while they have
had other feedback, this issue has never been reported by users either.  I
doubt there has been any X64 installations; it isn't that widely spread.


Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA
  Peter Duniho replied...
05-Nov-07 02:25 AM
On 2007-11-04 21:15:02 -0800, Dale <dale0973@nospam.nospam> said:


Then you are not likely to find the answer here, sorry to say.


While I appreciate the temptation of simply describing a problem and
hoping that someone recognizes it, that almost never works.  I hope I'm
mistaken and someone does reply with the answer.  But until you post a
concise-but-complete example of code that reliably reproduces the
problem, it's not likely someone can answer the question.  There's too
much missing in the code that you did post.


Well, you could try to find someone willing to test it on a
multi-processor machine.  It's true that race conditions often don't
manifest themselves until you run them on multi-processor computers.

Pete
  jeta replied...
05-Nov-07 04:52 AM
Hi Dale,

Then, is it possible for you to create a little sample project to
demonstrate this problem? This will help us to analyze the problem. Since
your problem is a bit specific, I would not expect other people have
encountered the same problem.

Can you provide a complete stack trace of the exception? Since you may get
two different exceptions, I agree with Pete that this may be caused by some
race condition or threading issue. Also, do you use any unmanaged code in
your application?

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
  dale097 replied...
05-Nov-07 07:23 PM
Thanks for your response, Peter.

You are probably right about the odds of finding the answer here but I did
want to try.  I have certainly seen hundreds if not thousands of issues get
answered without complete executable code being posted including many that I
have answered and that I have had answered.

But considering the difficulty of describing this and the complexity of
posting it, I will probably have to burn a support incident.  Oh well,  I
guess I have to use them for something.  :)

Thanks again for your help,

Dale
  dale097 replied...
05-Nov-07 07:34 PM
I just don't think I could hope to reproduce such an intermittent condition
with a scaled down application that can be posted here.  Offline from here, I
can provide the complete application code.

There is no unmanaged code or references to any non-.Net libraries.

Because I am using the BackgroundWorker to manage threading and it is in the
normal events of the BackgroundWorker where the errors are occuring, I would
expect this to work unless there was a bug in the framework.  There is only
one BackgroundWorker in the app.

I would not be disappointed or surprised if this issue ends up having to go
to product support for help.  Just let me know what you think.

Regards,

Dale Preston
--
Dale Preston
MCAD C#
MCSE, MCDBA
  dale097 replied...
05-Nov-07 07:36 PM
By the way, Peter, just in case you or anyone else wants to run the app on
Vista X64 or a multi-processor/core machine, the application can be
downloaded from
http://www.dalepreston.com/Blog/2007/03/id3-embed-pictures.html.  You can
verify the safety of the app to some degree by reading
http://www.siteadvisor.com/sites/dalepreston.com.

And it runs fine for me on 32-bit Vista on a Core 2 Duo machine but that's
only 2 cores.  The problem is only occuring on an 8-core machine.  Those may
be hard to find for testing :)

Thanks,

Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA
  dale097 replied...
05-Nov-07 07:44 PM
I guess because I typoed and used two punctuation marks in the address above,
the link is not interpreted correctly.  Either manually remove the trailing
period and space or try this link to download the application:

http://www.dalepreston.com/Blog/2007/03/id3-embed-pictures.html

Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA
  jeta replied...
06-Nov-07 01:00 AM
Hi Dale,

Thanks for your feedback.

The newsgroup support nature and support boundary confines that it is hard
to troubleshoot production application here.

Yes, due to the complexity of this issue, I would agree that contacting
Microsoft CSS phone support should be the most efficient way to resolve the
issue.

You can contact Microsoft Product Support at 1-(800)936-5800 or by choosing
one of the options listed at:
http://www.microsoft.com/services/microsoftservices/srv_support.mspx

If you need further help, please feel free to post, thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Create New Account
help
on how to get it working on win 7? thx. C# Discussions Windows 7 (1) Vista (1) Privileges (1) XP (1) Standard (1) There is nothing about your question that actually this before and knows how to help you with it. Pete it is talking about Vista in the link, and Windows 7 is Vista. So you might want to look at it from that standpoint and seek out more information, because Vista and Win 7 are not XP. ok I know it is not necessarily an issue not work. ie. 'Access to the path. . . . invalid' any help / insight here would be appreciated. Vista and Win 7 prevent an admin account running under UAC from doing things the admin admin account running the program under that account context. http: / / www.howtogeek.com / howto / windows-vista / enable-the-hidden-administrator-account-on-windows-vista / hmm, when i log onto the computer, it already has 2 accounts, and one of
DWF Upgrade Warning", 1) This code works great in XP, but in Windows 7 and Vista the Autodesk key and subkeys are duplicated instead of adding the subkey and value to The permissions for the Autodesk key seem to be the same between XP and 7 / Vista, though I am not too familiar with registry key permissions. Why the duplication? Any help Preferences User Interface Suppress (1) Design Review Preferences User Interface Suppress (1) Windows 7 (1) Vista (1) XP (1) Registry (1) SetValue (1) Upgrade (1) You have your terms mixed up DWF Upgrade Warning", 1) This code works great in XP, but in Windows 7 and Vista the Autodesk key and subkeys are duplicated instead of adding the subkey and value to The permissions for the Autodesk key seem to be the same between XP and 7 / Vista, though I am not too familiar with registry key permissions. Why the duplication? Any help had a special character embedded in my code, causing the duplicate registry entry in 7 / Vista. Moving on. . . . oftware \ Autodesk \ Design_ ey_ Warning", keywords: duplicate, registry, key description: I am attempting
VB6 Programm unter Vista. . . .NET Framework . . . erfordert die Ausf?hrung als Administrator. Wie kann ich das programmintern steuern, um ne Gr??e Peter VB - German Discussions Windows XP (1) Office 2003 (1) Error (1) Vista (1) Word (1) NET Framework (1) GetTempPath (1) VB (1) Moin, moin! Ein generelles Problem es, dass viele noch Informationen direkt in das Programmverzeichnis schreiben. Und dieses klappt halt bei Vista und neuer nicht mehr so ohne weiteres. Daraus zu schliessen, VB 2010 oder so w geht, Eintr?ge in die Registry. Das ist in diesem Fall unabdingbar. Wie kann ich "Vista" anwiesen: beim Eintragen die Berechtigung "mitgeben"? Gru? Peter Es gibt sicherlich viele, die mehr wissen GetPath", Erl 120 Resume GetPath_EXIT 130 Resume End Function - -- - Ende Quelltext - -- -- keywords: VB6, Programm, unter, Vista. . . description: . . . erfordert die Ausfhrung als Administrator. Wie kann ich das programmintern steuern, um den unkundigen
Discussions Visual Studio 2010 (1) Visual Studio (1) Silverlight (1) Windows 7 (1) Office (1) Vista (1) Linux (1) Error (1) HI again all I see that I already enquired re the .Net mess was dwarfed by a folder called winsxs. I had no idea that Vista / 7 was such a monstrosity. I thought it was outrageous that it takes up 7 turned up people complaining about winsxs folders growing to 30 or even 60 GB. So Vista / 7 is almost 10 times the size of XP, but it can bloat to some up again? You've been slapped down on that before as well. And besides, in Vista up, .NET is part of the OS - just as the vb runtimes were. And, I
any idea why? C# Discussions ThreadInterruptedException (1) ManualResetEvent (1) EventWaitHandle (1) AutoResetEvent (1) SynchronizationContext (1) ArgumentException (1) BackgroundWorker (1) ThreadStart (1) You are really asking two questions: ??? Why does not it thread and try to add it to the main form but at runtime it throws ArgumentException. void CreateAdditionalLabel() { var label2 = new Label(); label2.Text = "created from different thread"; Controls.Add(label2); / / <- ArgumentException } System.ArgumentException: Controls created on one thread cannot be parented to a control on a different thread