0

我已经看到关于同一主题的问题,但不知道如何解决这个问题。在我的游戏中,我使用两个线程一个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();
}

我怎么解决这个问题?已经尝试将逻辑循环粘贴到渲染循环之上,这让我的游戏变得如此缓慢。

谢谢

4

1 回答 1

5

“双线程”当然是问题所在。它们不能允许两个线程同时访问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);
        }
    }

其余的看起来也不那么健康,你没有确保你在两个线程之间正确地乒乓球,并且非常不清楚哪个线程拥有窗口。

于 2013-01-19T13:30:25.557 回答