AccessViolationException while disposing StringFormat on x64

  • Thread starter Thread starter Ihor Bobak
  • Start date Start date
I

Ihor Bobak

We have such a piece of code:

using (StringFormat tempFormat = GridProperties.StringFormat)
{
StringFormat tempFormat = GridProperties.StringFormat;
StringFormat stringFormat = new StringFormat(tempFormat);
stringFormat.Alignment =
(StringAlignment)formatRule.Layout.AlignHorizontal;
stringFormat.LineAlignment =
(StringAlignment)formatRule.Layout.AlignVertical;
stringFormat.FormatFlags = tempFormat.FormatFlags;
GridProperties.StringFormat = stringFormat;
}

On x86 this code works fine and never crashes. On x64 (both on Vista Busines
and XP 64-bit) this code from time to time crashes with
"AccessViolationException occurs while disposing instance of class
StringFormat."

Exception occurs rarely, reasons are not clear.

We tried to find the solution using google search, but seems as noone else
got such problems before.

Would you be so kind as to tell us what can we do in order to dispose
StringFormat instance?

--
Best regards,
Ihor.

P.S. We are a valid MS Certified Partner. I am not sure if my posting alias
is fine, but I am expecting to get an answer. Thanks.
 
Hi Ihor,

Thank you for using Microsoft Managed Newsgroup Service, my name is Zhi-Xin
Ye, it's my pleasure to work with you on this issue.

In the code you posted, you create a temporary StringFormat object from the
GridProperties.StringFormat object, modifiy some properties and assign it
back to the GridProperties.StringFormat object, but why don't you just
modify the properties on the GridProperties.StringFormat object direcly?

I look forward to your reply.

Sincerely,
Zhi-Xin Ye
Microsoft Managed Newsgroup Support Team

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 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. 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/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
In the code you posted, you create a temporary StringFormat object from the
GridProperties.StringFormat object, modifiy some properties and assign it
back to the GridProperties.StringFormat object, but why don't you just
modify the properties on the GridProperties.StringFormat object direcly?

When copy-pasting the code into here we've occasionally inserted a redundant
row. The code was like this:

using (StringFormat tempFormat = GridProperties.StringFormat)
{
StringFormat stringFormat = new StringFormat(tempFormat);
stringFormat.Alignment =
(StringAlignment)formatRule.Layout.AlignHorizontal;
stringFormat.LineAlignment =
(StringAlignment)formatRule.Layout.AlignVertical;
stringFormat.FormatFlags = tempFormat.FormatFlags;
GridProperties.StringFormat = stringFormat;
}

Look what is happening:
1) we get a reference of GridProperties.StringFormat
2) we create a new object stringFormat
3) we assign GridProperties.StringFormat a new reference
4) "using" disposes GridProperties.StringFormat (=tempFormat)

Why we do this? Because in another piece of code we somewhere do
ReferenceEquals() with these objects, so we really need another instance.

But this does not matter. It matters only the fact that
StringFormat.Dispose() crashes. Why can't we do this?
 
Hi Ihor,

Thank you for the feedback.

However, the current information is not enough for us to analysis the root
cause.

Is it possible for you to create a concise-but-complete sample and send to
me for local reproduce? My email is (e-mail address removed). I will be happy
to help you analyse the problem.

Anyway, if you want to debug the problem yourself, you can use debugging
tools like Windbg to find the root cause. Here are some links for your
reference.

How to debug application crash/hang in production environment?
http://blogs.msdn.com/msdnts/archive/2006/11/24/how-to-debug-application-cra
sh-hang-in-production-environment.aspx

XCrashReport : Exception Handling and Crash Reporting - Part 3
http://www.codeproject.com/KB/debug/XCrashReportPt3.aspx

Clrdump
http://www.debuginfo.com/tools/clrdump.html

If you have any questions or concerns, please feel free to let me know.

Best Regards,
Zhi-Xin Ye
Microsoft Managed Newsgroup Support Team

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Thank you for your reply.
We understand that such situation is hardly reproducible (I cannot reproduce
such behavior in small sample application myself). Thought may be someone
came across similar error and can help with solution.
We’ll try to find workaround not to dispose StringFormat instances so
frequently in our code.
 
When copy-pasting the code into here we've occasionally inserted a redundant
row. The code was like this:

using (StringFormat tempFormat = GridProperties.StringFormat)
{
StringFormat stringFormat = new StringFormat(tempFormat);
stringFormat.Alignment =
(StringAlignment)formatRule.Layout.AlignHorizontal;
stringFormat.LineAlignment =
(StringAlignment)formatRule.Layout.AlignVertical;
stringFormat.FormatFlags = tempFormat.FormatFlags;
GridProperties.StringFormat = stringFormat;
}

Look what is happening:
1) we get a reference of GridProperties.StringFormat
2) we create a new object stringFormat
3) we assign GridProperties.StringFormat a new reference
4) "using" disposes GridProperties.StringFormat (=tempFormat)

Why we do this? Because in another piece of code we somewhere do
ReferenceEquals() with these objects, so we really need another instance.

But this does not matter. It matters only the fact that
StringFormat.Dispose() crashes. Why can't we do this?

Is it possible that the StringFormat object you are disposing is still
in use? It may be that the GridProperties object uses the
StringFormat object in several places, and when you give it a new
StringFormat that does not remove its references to the old one.

This may be similar to fonts in windows forms. By default children
use the same Font object as their parents. If you replace the
original Font object of a control and dispose the old one, you will
cause problems because that object is still being used by other
controls.

It sometimes can be difficult to know when it is safe to dispose an
object in .NET.
 
Hi Yuriy,

Thanks for your feedback.

Being unable to reproduce the problem, I have to guess the cause.

In the code you posted, i.e.

using (StringFormat tempFormat = GridProperties.StringFormat)
{
.....
}

The GridProperties.StringFormat will be disposed when exiting the using
block, so if you use GridProperties.StringFormat in many places, there will
be a conflict when exiting this using block.

One way to workaround this is using the StringFormat.Clone() method, this
method gives you a copy of the GridProperties.StringFormat object, for
example:

using (StringFormat tempFormat = (StringFormat)
GridProperties.StringFormat.Clone() )
{
.......
}

Please try my suggestion and let me know whether it make sense to you or
not.

Best Regards,
Zhi-Xin Ye
Microsoft Managed Newsgroup Support Team

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top