【问题标题】:System.Drawing.Graphings.SmoothingMode getter throws ArgumentException "Parameter is not valid"System.Drawing.Graphings.SmoothingMode getter 抛出 ArgumentException“参数无效”
【发布时间】:2019-02-26 06:07:14
【问题描述】:

我有一个使用 DotNetBar 3rd 方 UI 库的大型资源密集型 C# GUI 应用程序。

有时,它会因以下异常和调用堆栈而失败:

====================================
 ERROR 
====================================
Exception type: ArgumentException
Parameter is not valid.

====================================
 CALL STACK 
====================================
   at System.Drawing.Graphics.get_SmoothingMode()
   at DevComponents.DotNetBar.⍜.PaintCaptionBackground(FormCaptionRendererEventArgs e)
   at DevComponents.DotNetBar.Rendering.Office2007Renderer.DrawFormCaptionBackground(FormCaptionRendererEventArgs e)
   at DevComponents.DotNetBar.OfficeForm.ὀ(Graphics ٠)
   at DevComponents.DotNetBar.OfficeForm.ᲀ()
   at DevComponents.DotNetBar.OfficeForm.WindowsMessageNCActivate(Message& m)
   at DevComponents.DotNetBar.RibbonForm.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

在栈顶失败的调用只是访问SmoothingMode属性,而属性getter没有参数,所以很难知道“参数无效”可能意味着什么。

此异常偶尔发生,它不是 100% 可重现的,但似乎与我的应用程序中的高资源使用率相关(它发生在将特定的大型“项目”加载到应用程序中时)而其他较小的项目确实如此不会触发这种情况,即使大型和小型项目都以相同的方式使用 DotNetBar UI。

什么会导致SmoothingMode 属性抛出 ArgumentException?

【问题讨论】:

  • 在您的应用打开一个大型项目后,有多少 GDI 对象处于活动状态?任务管理器(更多详细信息) - 详细信息选项卡 - 鼠标右键单击标题 - 选择列 - GDI 对象。
  • @LarsTech 我确实怀疑 GDI 对象泄漏,但根据任务人员的说法,加载大型项目后大约为 480。这大大低于 Outlook.exe 或 devenv.exe 正在使用的数字,所以看起来还可以。我想我在某个地方读到了每个应用程序大约 10k 的限制。
  • SmoothingMode 可能出于多种原因引发 ArgumentException。在这种情况下,看起来对本机 gdiplus.dll 方法 GdipGetSmoothingMode 的调用返回了状态 2。传入的唯一参数是使用图形 NativeGraphics 指针创建的 HandleRef 结构。这就是我能深入研究的范围了。

标签: c# gdi system.drawing dotnetbar


【解决方案1】:

解决了这个问题,结果证明拥有System.Drawing.Graphics 对象的对象已被处置。

在 DotNetBar 库中,DotNetBar.BufferedBitmap 对象正在执行一些低级调用以分配位图,然后使用 Graphics.FromHdc(IntPtr) 返回图形。如果BufferedBitmap 在使用前被释放,那么Graphics 对象上的所有属性都会在您尝试访问它们时引发异常。

位图在使用之前被处理的原因很复杂,是我的应用程序与DotNetBar交互的结果。简而言之:WM_NCACTIVATE 消息触发了一些代码来重绘窗口标题,但是这个标题绘制代码在我的应用程序中触发了 OnPaint,并间接触发了正在处理另一个 WM_NCACTIVATE 的 WndProc,从而调用了标题- 在自身下方绘制代码。一级标题绘制代码正在处理另一级未完成使用的位图。

【讨论】:

    猜你喜欢
    • 2012-05-01
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2012-08-10
    • 2018-11-11
    相关资源
    最近更新 更多