C# 单一游戏窗口在拖动时冻结

C# 单一游戏窗口在拖动时冻结,c#,xna,monogame,C#,Xna,Monogame,我正在用MonoGame开发一款网络游戏,每当拖动窗口时,我都会遇到游戏冻结的问题。在寻找解决方案的过程中,我找到了一个描述如何注入自定义tick系统的方法 然而,虽然这个答案适用于XNA,但所需的反射调用会在MonoGame中引发异常。有没有人有其他解决方案可以让游戏在被拖动时继续更新 引发异常的代码部分是: // Exception on this line object host = typeof(Game).GetField("host", BindingFlags.

我正在用MonoGame开发一款网络游戏,每当拖动窗口时,我都会遇到游戏冻结的问题。在寻找解决方案的过程中,我找到了一个描述如何注入自定义tick系统的方法


然而,虽然这个答案适用于XNA,但所需的反射调用会在MonoGame中引发异常。有没有人有其他解决方案可以让游戏在被拖动时继续更新

引发异常的代码部分是:

// Exception on this line
object host = typeof(Game).GetField("host", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this);
host.GetType().BaseType.GetField("Suspend", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(host, null);
host.GetType().BaseType.GetField("Resume", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(host, null);
例外情况如下:

CardCatacombs.exe中发生类型为“System.NullReferenceException”的未处理异常

其他信息:对象引用未设置为对象的实例


据我所知,这个问题是通过在项目引用中导入System.Windows.Forms程序集并忽略XNA提供答案的反射组件来解决的,因为MonoGame不再使用游戏中的“主机”字段


感谢Sahuagin的支持。

由于MonoGame不再使用游戏中的“主机”字段,因此通过在项目引用中导入System.Windows.Forms程序集并忽略为XNA提供的答案中的反射组件,此问题得以解决


感谢Sahuagin的支持。

基于另一个答案,使用
System.Timers.Timer
而不是
System.Windows.Forms.Timer

public class MyGame : Game {
   bool manualTick;
   int manualTickCount = 0;
   Timer mTimer;

   public MyGame() {
      mTimer = new Timer {
         Interval = (int)(TargetElapsedTime.TotalMilliseconds)
      };

      mTimer.Elapsed += (s, e) => {
         if (manualTickCount > 2) {
            manualTick = true;
            Debug.Print("manual tick");
            Tick();
            manualTick = false;
         }

         manualTickCount++;
      };

      // required to prevent exception on exit
      // otherwise the timer keeps running after the window closes
      Exiting += (s, e) => mTimer.Dispose();

      // it might be needed to do something similar in the Dispose event
      // if the game can be disposed without exiting
   }

   // the constructor is too early to start the timer, so put it in initialize
   protected override void Initialize() {
      mTimer.Start();
      base.Initialize();
   }

   // and lastly, in Update
   protected override void Update(GameTime pGameTime) {
      if (!manualTick) {
         manualTickCount = 0;
         Debug.Print("not manual");
      }
      base.Update(pGameTime);
   }

根据另一个答案,使用
System.Timers.Timer
而不是
System.Windows.Forms.Timer

public class MyGame : Game {
   bool manualTick;
   int manualTickCount = 0;
   Timer mTimer;

   public MyGame() {
      mTimer = new Timer {
         Interval = (int)(TargetElapsedTime.TotalMilliseconds)
      };

      mTimer.Elapsed += (s, e) => {
         if (manualTickCount > 2) {
            manualTick = true;
            Debug.Print("manual tick");
            Tick();
            manualTick = false;
         }

         manualTickCount++;
      };

      // required to prevent exception on exit
      // otherwise the timer keeps running after the window closes
      Exiting += (s, e) => mTimer.Dispose();

      // it might be needed to do something similar in the Dispose event
      // if the game can be disposed without exiting
   }

   // the constructor is too early to start the timer, so put it in initialize
   protected override void Initialize() {
      mTimer.Start();
      base.Initialize();
   }

   // and lastly, in Update
   protected override void Update(GameTime pGameTime) {
      if (!manualTick) {
         manualTickCount = 0;
         Debug.Print("not manual");
      }
      base.Update(pGameTime);
   }

“所需的反射调用在MonoGame中引发异常”哪个异常?你的代码是什么样子的?可能是你想要的:我已经用更多的信息更新了我的问题。不幸的是,第二篇文章提到的是图形缩放,而不是游戏逻辑更新。例外是因为
game
对象上不再有
host
字段。这可能意味着取消钩挂
Suspend
Resume
的第一步是不必要的。您是否尝试过在不执行第一部分的情况下设置计时器?在尝试实现计时器时,我注意到MonoGame不允许使用System.Windows.Form.timer类。当我尝试从timer Appeased事件(使用System.Timers.timer)中调用Tick()时,会从Tick()中引发“NullReferenceException”错误。“所需反射调用在MonoGame中引发异常”哪个异常?你的代码是什么样子的?可能是你想要的:我已经用更多的信息更新了我的问题。不幸的是,第二篇文章提到的是图形缩放,而不是游戏逻辑更新。例外是因为
game
对象上不再有
host
字段。这可能意味着取消钩挂
Suspend
Resume
的第一步是不必要的。您是否尝试过在不执行第一部分的情况下设置计时器?在尝试实现计时器时,我注意到MonoGame不允许使用System.Windows.Form.timer类。当我尝试从timer Appeased事件中调用Tick()时(使用System.Timers.timer),会从Tick()中抛出一个“NullReferenceException”错误