2016-05-13 59 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'方法,並將它們合爲一體。到那時,調度員用更少的定時器工作,我沒有任何錯誤。因爲我不知道究竟是什麼造成了這個問題,所以我想我最終會以某種方式修復它。