开发者

"The operation completed successfully" exception

I have a custom method that finds the largest size to use for a given string and font to fill a given box without cutting off the text. To test it, I created a service that cycles through a few different strings and a few dif开发者_开发技巧ferent fonts and does batches of them in a Parallel.For loop. When this service is running, all the CPU cores on a system are at %90-%100. After running for 8 or 9 hours, it will start throwing exceptions. It will still work most of the time, but there will be the occasional exception or burst of exceptions.

The innermost exception has the message "The operation completed successfully" and is originating from the WidthIncludingTrailingWhitespace accessor on a FormattedText object. The call stack looks like this:

   at MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d)
   at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
   at System.Windows.Threading.Dispatcher..ctor()
   at System.Windows.Threading.Dispatcher.get_CurrentDispatcher()
   at System.Windows.Media.TextFormatting.TextFormatter.FromCurrentDispatcher(TextFormattingMode textFormattingMode)
   at System.Windows.Media.FormattedText.LineEnumerator..ctor(FormattedText text)
   at System.Windows.Media.FormattedText.DrawAndCalculateMetrics(DrawingContext dc, Point drawingOffset, Boolean getBlackBoxMetrics)
   at System.Windows.Media.FormattedText.get_Metrics()
   at System.Windows.Media.FormattedText.get_WidthIncludingTrailingWhitespace()
   ...My Library Here...

In researching this, I found that undisposed drawing objects (Graphics, Icons, etc) are a common cause for this, but I could not find any Disposable objects in use. The text sizing code uses WPF classes (FontFamily, FormattedText, and Typeface) and none of them implement IDisposable.

I have perfmon monitoring the process and while memory use, handle count, and thread count do vary quite a bit, they never skyrocket out of control. This tells me it probably isn't a handle leak. What else could it be?

UPDATE: I have been running the test for a few days now with one significant change: it is doing a regular for instead of a parallel for. It hasn't crashed yet and perfmon shows horizontal lines with very little variance. Perhaps this is an issue with parallelization and not WPF text rendering?


It looks like exception was raised when WPF tried to allocate native Win32 window handle for another new Dispatcher. Maybe you have reached the maximum amount of handles for your process?

Did you try to force garbage collection on each iteration? The most WPF classes doesn't implement IDisposable, but they still use unmanaged resources, which are managed inside WPF.

There is another way for overflow I can imagine. The CurrentDispatcher property creates a new Dispatcher for each thread. Every Dispatcher never stop until InvokeShutdown will be called. So it means that a thread where a Dispatcher works will never be terminated, because there is no Window and there is nobody to press the Close button. Perhaps it forces Parallel.For implementation to allocate a new Thread for a next iteration, which also need another new Dispatcher and another new handle. Unfortunately, I don't have much experience in using Parallel, so this is only supposition.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜