この gamedev.stackexchange スレッドで説明されているゲーム ループを使用しています: https://gamedev.stackexchange.com/questions/67651/what-is-the-standard-c-windows-forms-game-loop
Debug ビルド タイプを使用している場合はすべて問題なく動作しますが、Release を実行すると、null 参照例外が発生します。コードの最適化を有効にした場合にのみ発生するようです。これは、同じことを行うベアボーンの例です。フォームは完全に空白で、この例ではボタン/コントロールはありません。
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 と一連の外部コードだけです。
何が原因なのかはわかりませんが、Idle イベントへのサブスクリプションをコメントアウトするとエラーが発生しないため、PeekMessage の呼び出しに関係があることはわかっています。
副次的な質問として、ここで "NativeMessage" 構造体を宣言する必要があるのはなぜですか? カットしても問題はないようですが、このゲームループを使用するすべての例にはそれが含まれています。