“操作成功完成”例外

时间:2011-07-08 13:23:28

标签: wpf exception windows-services hwnd

我有一个自定义方法,可以找到用于给定字符串和字体的最大大小,以填充给定的框而不会切断文本。为了测试它,我创建了一个服务,它循环遍历几个不同的字符串和几个不同的字体,并在Parallel.For循环中完成批量处理。运行此服务时,系统上的所有CPU核心均为%90-%100。运行8或9小时后,它将开始抛出异常。它大部分时间仍然可以工作,但会偶尔出现异常或异常突发。

最内层的异常具有消息“操作已成功完成”,并且源自FormattedText对象上的WidthIncludingTrailingWhitespace访问器。调用堆栈如下所示:

   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...

在研究这个时,我发现未使用的绘图对象(图形,图标等)是这个的常见原因,但我找不到任何正在使用的Disposable对象。文本大小调整代码使用WPF类(FontFamily,FormattedText和Typeface),但它们都没有实现IDisposable。

我有perfmon监视进程,虽然内存使用,句柄计数和线程数确实变化很大,但它们从未飙升失控。这告诉我它可能不是手柄泄漏。还有什么呢?

更新:我已经运行了几天测试,但有一个重大变化:它正在进行常规测试,而不是并行测试。它尚未崩溃,perfmon显示水平线,方差很小。也许这是并行化而不是WPF文本呈现的问题?

1 个答案:

答案 0 :(得分:1)

当WPF尝试为另一个新的Dispatcher分配本机Win32窗口句柄时,看起来似乎引发了异常。也许您已达到流程的最大处理量?

您是否尝试在每次迭代时强制进行垃圾回收?大多数WPF类没有实现IDisposable,但它们仍然使用非托管资源,这些资源在WPF中进行管理。

我可以想象还有另一种溢出方式。 CurrentDispatcher属性为每个线程创建一个新的Dispatcher。在调用InvokeShutdown之前,每个Dispatcher都不会停止。因此,这意味着Dispatcher工作的线程永远不会终止,因为没有Window,没有人按下Close按钮。也许它强制Parallel.For实现为下一次迭代分配一个新的Thread,它还需要另一个新的Dispatcher和另一个新的句柄。不幸的是,我没有太多使用Parallel的经验,所以这只是假设。

相关问题