【发布时间】:2014-09-09 07:59:09
【问题描述】:
我有一个游戏,有几个敌人,每个都在自己的线程中运行以进行移动和绘图。敌人被绘制在面板上,因此他们的线程必须访问面板的图形。我已经使用Lock 保护了CreateGraphics 调用,当我想ReleaseHdc 面板的图形时,我得到一个System.ArgumentException,即使我调用ReleaseHdc 方法时没有任何参数.
以下是相关代码(p 是作为静态变量传递下来的 Panel 引用并指向正确的控件):
//Member region
internal Bitmap Img = new Bitmap(Image.FromFile(@"Enemy.png"), Size);
internal static readonly object _Lock = new object();
//from enemy's custom Move() method
lock (_Lock)
{
Graphics gfx = p.CreateGraphics();
gfx.DrawImage(Img, Location);
gfx.ReleaseHdc(); // gfx.Dispose() works here
}
考虑到我需要在自己的线程中将每个元素绘制到同一个面板上的多线程访问,是否有人知道我为什么会收到此错误和/或如何修复它?
[编辑]
使用gfx.Dispose() 而不是ReleaseHdc() 就可以了。
虽然结果并不令人满意,因为我得到了一个非常不稳定的图像,敌人闪烁。这可能是经常重复绘制它们的问题,并且与我的问题无关 - 或者这个问题与我如何处理多个线程之间存在联系?
【问题讨论】:
-
你在玩一个非常危险的游戏。那个锁当然是个好主意,但是你没有把同样的锁放在面板的 OnPaint() 方法中。从 Panel 派生您自己的类并覆盖 OnPaint() 和 OnPaintBackground()。使用 ReleaseHdc() 是错误的,您必须改用 Dispose()。可能会奏效,但不要抱太大希望。
-
在创建多个控件的
Graphpics实例时是否存在冲突?是否可以同时存在一个线程,从而不可能每个线程都创建自己的线程?我现在正在修改我的程序以从Panel派生,但无论如何我都会很高兴。 -
在多个线程中创建图形实例很好。使用 DpiX 之类的属性很好。像 MeasureString() 这样的东西很好。实际上使用它们在屏幕上绘画,这是一个危险的游戏。当多个线程渲染到同一个屏幕区域时,也很难推断你最终会得到什么,最终结果总是不可预测的。
-
您知道这是如何正确完成的吗?我可以重写我的程序,但现在我不知道如何从多个线程将
DrawImage转换为Panel。或者是使用来自线程的更新参数(如位置)从后台线程绘制面板上的所有内容的秘诀,也许? -
游戏代码中的样板是渲染到后台缓冲区并将其blit到屏幕上。通过绘制位图很简单,可以由工作线程安全地完成。
标签: c# image graphics argumentexception