gpt4 book ai didi

c# - 什么会导致双缓冲终止我的应用程序?

转载 作者:太空狗 更新时间:2023-10-29 18:25:30 26 4
gpt4 key购买 nike

我有一些使用 GDI+ 绘制到屏幕上的自定义 (winforms) 组件。

为了防止重绘时闪烁,我决定启用双缓冲,所以我在构造函数中添加了一行:

public ColourWheel()
{
InitializeComponent();
this.DoubleBuffered = true;
}

在该组件 (ColourWheel) 上运行良好。当我将同一行添加到我的其他两个(类似结构的)组件中的任何一个的构造函数时,我得到了一些奇怪的症状:

  1. 当我尝试运行带有组件的表单时,我在 Application.Run(new Form()); 上收到参数异常。
  2. 如果我切换到设计模式,我会收到一条错误消息,指出组件有一个与参数有关的未处理异常。

我是否对其中一个或所有打开双缓冲似乎并不重要,它仍然适用于 ColourWheel,但不是其他。

郑重声明,我还尝试了其他一些 double buffering技术。

什么可能导致双缓冲在一个组件上起作用,而在其他组件上不起作用?


编辑:这是运行时症状的异常详细信息:

System.ArgumentException was unhandled Message=Parameter is not valid. Source=System.Drawing StackTrace: at System.Drawing.Graphics.GetHdc() at System.Drawing.BufferedGraphics.RenderInternal(HandleRef refTargetDC, BufferedGraphics buffer) at System.Drawing.BufferedGraphics.Render() at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.UserControl.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at TestForm.Program.Main() in D:\Documents and Settings\Tom Wright\My Documents\Visual Studio 2010\Projects\ColourPicker\TestForm\Program.cs:line 18 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:


编辑 2:来自导致问题的两个组件之一(更复杂的)的 OnPaint 处理程序:

private void ValueSlider_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = e.Graphics)
{
g.DrawImage(this.gradientImage, new Rectangle(0, 0, paintArea.Width, paintArea.Height));
if (this.showmarker)
{
ColourHandler.HSV alt = ColourHandler.RGBtoHSV(new ColourHandler.RGB(this.SelectedColour.R, this.SelectedColour.G, this.SelectedColour.B));
alt.Saturation = 0;
alt.value = 255 - alt.value;
using (Pen pen = new Pen(ColourHandler.HSVtoColour(alt)))
{
pen.Width = (float)MARKERWIDTH;
g.DrawRectangle(pen, 0 - pen.Width, this.brightnessPoint.Y - MARKERWIDTH, this.paintArea.Width + (pen.Width * 2), MARKERWIDTH * 2);
}
}
}
}

最佳答案

您不应该处置在 Paint 事件期间借给您的 Graphics 对象,而这正是您的 using block 不正确的做法.

症状是下次触发 Paint 事件时,您会得到相同的 Graphics 对象,但它不再绑定(bind)到内存中的 HDC,导致 Graphics.GetHdc() 失败,如您的堆栈跟踪所示。

  1. 它有可能超过单个 Paint 事件(双缓冲很可能就是这种情况,尽管如果 CS_OWNDC 设置窗口样式)。

  2. Paint 事件可以有多个处理程序。

因此,事件处理程序不应在 Graphics 对象上调用 Dispose 或允许 using block 这样做。相反,.NET 框架会在 Paint 事件处理完成后适本地清理资源。

关于c# - 什么会导致双缓冲终止我的应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9134181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com