2016-05-13 56 views
0

我正在为使用WPF的计算机科学项目创建一个节奏游戏(不像吉他英雄 - 但带有箭头的下降游戏),并且出现了一些性能问题。我使用了很多DispatcherTimers,这会减慢应用程序的运行速度并导致它冻结。为了解决这个问题,我找到了一个answer,建议使用System.Threading.Timers。调度员没有出现在课堂上 - 使用System.Threading.Timer

我明白,通过使用这个,我为这些定时器创建了新线程,这些定时器允许它们在同一时间运行而不会减慢应用程序的速度。

我定时器创建方法是这样的:

private void SetTimers() 
    { 
     _arrowKeytimer = new Timer(new TimerCallback(Timer_ArrowTick), null, 0, 775); 
     //_timerHealth = new Timer(new TimerCallback(Timer_HealthTick), null, 0, 775); 
     _MediaTimer = new Timer(new TimerCallback(Timer_MediaTick), null, 0, 775); 
     _leftFall = new Timer(new TimerCallback(LeftArrowFall), null, 0, 775); 
     _rightFall = new Timer(new TimerCallback(RightArrowFall), null, 0, 775); 
     _upFall = new Timer(new TimerCallback(UpArrowFall), null, 0, 775); 
     _downFall = new Timer(new TimerCallback(DownArrowFall), null, 0, 775); 
     _spawner = new Timer(new TimerCallback(Timer_SpawnTick), null, 0, 775); 
    } 

有一次,我已经改变了从旧蜱我所有的方法,我跑的程序。瞬间我得到'不能从另一个线程访问对象。'例外。

望着这answer,我用的是造成异常打勾Dispatcher.Invoke方法:

private void DownArrowFall(object state) 
    { 
     this.Dispatcher.Invoke((Action)(() => //Added the Invoke thing that the answer said to do 
     { 
     double y; 
     for (int z = 0; z < TheDirector.DownArrowList.Count; z++) // Before I would get the exception on this line 
     { 
      if ((string)TheDirector.DownArrowList[z].Tag == "Spawned") 
      { 
       y = Canvas.GetTop(TheDirector.DownArrowList[z]); 
       y += FallSpan; 
       Canvas.SetTop(TheDirector.DownArrowList[z], y); 
      } 
     } 
     double position = Canvas.GetTop(TheDirector.DownArrowList[0]); 
     if (position >= 700) 
     { 
      TheDirector.RemoveDownArrow(); 
     } 
     })); 
    } 

我再次运行程序,并最终抛出同样的异常在我的画法在我的LeftArrow类中(在屏幕上绘制向下的左箭头)。然而,并称调用没有工作:

public void Draw() 
    {   
     this.Dispatcher.Invoke((Action)(() => //Apparently 'Dispatcher' doesn't exist 
     { 

      for (int x = 0; x < _arrows.Count; x++) 
      { 
       if ((string)_arrows[x].Tag == "NotSpawned") 
       { 
        _arrows[x].Tag = "Spawned"; 
        _canvas.Children.Add(_arrows[x]); 
        Canvas.SetLeft(_arrows[x], Coordinates.LeftArrowX); 
        Canvas.SetTop(_arrows[x], Coordinates.Y); 
        break; 
       } 
      } 
     })); 
    } 

我不知道我在做什么 - 我已经检查了所有关于这个问题的答案。我知道我的_arrows列表是由主线程创建的,这就是我得到这些例外的原因,但我不知道该如何处理它们。

谢谢。

关于我的更多信息:

每个ArrowFall定时器通过所有箭头的屏幕上的列表中进行搜索(取决于它是什么列表中,有四个,1左箭头,第2右箭头等等),并在将新位置设置到画布之前在其Y坐标中添加一定量。

所以基本上,我只需要两个对象 - 我添加到的画布和其中一个列表。其他线程只需要访问他们自己的列表和画布。

注意:列表存储在名为Director的类(在此例中命名为实例是TheDirector)中,矩形列表作为属性。这些属性返回由每个箭头的类填充的列表 - 类'RightArrow','LeftArrow'等。

+0

当你有8个完全不同步的线程在你的游戏逻辑上运行时,你仍然无法解决* real *问题。划痕这种方法。 Google为下一个“wpf游戏循环”。 –

+0

这是与每个计时器有自己的线程,我收集? –

+0

我检查了游戏循环 - 并且它不以我想要的方式工作。比赛比以前更慢。具有不同持续时间的定时器是否有帮助?如果没有,那么上述需要工作。我总是可以切断几个定时器来处理更少的线程。 –

回答

0

最后,我脱掉了几个定时器,并通过大量的' ArrowFall'方法,并将它们合为一体。到那时,调度员用更少的定时器工作,我没有任何错误。因为我不知道究竟是什么造成了这个问题,所以我想我最终会以某种方式修复它。