我使用這個gamedev.stackexchange線程討論的遊戲循環時: https://gamedev.stackexchange.com/questions/67651/what-is-the-standard-c-windows-forms-game-loop代碼優化導致空引用異常使用的PeekMessage
一切是偉大的工作,如果我使用調試版本類型,但是當我去要做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」結構?如果我把它切掉,它似乎不會引起問題,但每個使用這個遊戲循環的例子都包含它。
你能否將代碼縮減爲一個可展示行爲的簡短可編譯示例? –
完成,這是我所說的最簡單的例子。 Console.WriteLine是我的模擬器更新/渲染的地方。 – ALLCAPS