我已经看过同一主题的问题,但无法弄清楚如何解决这个问题。在我的游戏中,我使用两个线程一个Logic
线程和UI
线程。这是我遇到的问题
System.InvalidOperationException: Object is currently in use elsewhere.
at System.Drawing.Graphics.FromImage(Image image)
at GECS.Core.Game.UpdateLoop() in c:\Us....ore\Game.cs:line 82
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()
我只在UI线程上渲染。这是我的渲染循环。我把它放在构造函数中。
while (true) {
if (!Created) {
break;
}
if (Win32.PeekMessage(out msg, IntPtr.Zero, 0, 0, (uint)Win32.PM.REMOVE)) {
if (msg.message == (uint)Win32.WindowsMessage.WM_QUIT) {
break;
} else {
Win32.TranslateMessage(ref msg);
Win32.DispatchMessage(ref msg);
}
} else {
Text = Global.TITLE;
now = GetCurrentTime();
Graphics front = Graphics.FromHwnd(Handle);
front.DrawImage(backBuffer, 0, 0);
front.Dispose();
}
}
我的逻辑循环
while (Created) {
now = GetCurrentTime();
while (now > game_time) {
elapsedTime = 1000/Global.ACTUAL_STEPS_FOR_SECOND;
Update(elapsedTime);
Map.UpdateObjects(elapsedTime);
game_time += step_size;
}
Graphics g = Graphics.FromImage(backBuffer); // This line is error
g.Clear(Color.WhiteSmoke);
Render(g);
g.Dispose();
}
我该如何解决这个问题?已经尝试在渲染循环上粘贴逻辑循环,这使我的游戏变得如此缓慢。
由于
答案 0 :(得分:6)
“两个线程”当然是问题所在。它们不允许两个线程同时访问 backBuffer 。您必须使用锁来防止这种情况发生。大致是:
private object bufferLock = new object();
...
using (var front = Graphics.FromHwnd(Handle)) {
lock (bufferLock) {
front.DrawImage(backBuffer, 0, 0);
}
}
和
lock (bufferLock) {
using (var g = Graphics.FromImage(backBuffer) { // No more error
g.Clear(Color.WhiteSmoke);
Render(g);
}
}
其余的看起来也不健康,你没有确定你在两个线程之间正确地打乒乓,并且很不清楚什么线程拥有该窗口。