【问题标题】:"The operation completed successfully" exception“操作成功完成”异常
【发布时间】:2011-10-01 06:57:35
【问题描述】:

我有一个自定义方法,可以找到用于给定字符串和字体的最大尺寸来填充给定框,而不会切断文本。为了测试它,我创建了一个服务,该服务循环遍历几个不同的字符串和几个不同的字体,并在 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 监控进程,虽然内存使用、句柄计数和线程计数确实有很大差异,但它们从来没有暴涨失控。这告诉我它可能不是句柄泄漏。还能是什么?

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

【问题讨论】:

    标签: wpf exception windows-services hwnd


    【解决方案1】:

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

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

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

    【讨论】:

    • 我在进程上运行 perfmon,并且句柄使用率上下跳动很多 - 它没有上升趋势,所以我认为这不是问题。我曾尝试定期强制垃圾收集 - 它没有帮助。最后一个建议很有趣。 Perfmon 没有显示任何线程的上升趋势,但这与任何线程一样好。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-01-22
    • 2016-08-29
    • 2022-11-16
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 2012-02-12
    相关资源
    最近更新 更多