我正在使用这个 gamedev.stackexchange 线程中讨论的游戏循环: https ://gamedev.stackexchange.com/questions/67651/what-is-the-standard-c-windows-forms-game-loop
如果我使用 Debug 构建类型,一切都很好,但是当我去做 Release 时,我得到一个空引用异常。看起来只有当我启用代码优化时才会发生这种情况。这是一个做同样事情的准系统示例。表单是完全空白的,在这个例子中没有按钮/控件。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Sharp8
{
public partial class DebugForm : Form
{
public DebugForm()
{
InitializeComponent();
Application.Idle += GameLoop;
}
private void GameLoop(object sender, EventArgs e)
{
while (IsApplicationIdle())
{
Console.WriteLine("Game Updates/Rendering!");
}
}
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr Handle;
public uint Message;
public IntPtr WParameter;
public IntPtr LParameter;
public uint Time;
public Point Location;
}
[DllImport("user32.dll")]
static extern bool PeekMessage(out Message message, IntPtr window, uint messageFilterMinimum, uint messageFilterMaximum, uint shouldRemoveMessage);
private bool IsApplicationIdle()
{
Message result;
return !PeekMessage(out result, IntPtr.Zero, 0, 0, 0);
}
}
}
当我运行它时,据说异常发生在 forms.dll 内的外部代码中,它是在启动此表单的 Application.Run("etc") 之后抛出的。堆栈跟踪并没有真正的帮助,它只是 Application.Run 和一堆外部代码。
我不确定是什么原因造成的,但我知道这与调用 PeekMessage 有关,因为如果我注释掉对 Idle 事件的订阅,则不会发生错误。
作为一个附带问题,为什么我需要在这里声明“NativeMessage”结构?如果我剪掉它似乎不会引起问题,但是使用此游戏循环的每个示例都包含它。