我正在爲使用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'等。
當你有8個完全不同步的線程在你的遊戲邏輯上運行時,你仍然無法解決* real *問題。劃痕這種方法。 Google爲下一個「wpf遊戲循環」。 –
這是與每個計時器有自己的線程,我收集? –
我檢查了遊戲循環 - 並且它不以我想要的方式工作。比賽比以前更慢。具有不同持續時間的定時器是否有幫助?如果沒有,那麼上述需要工作。我總是可以切斷幾個定時器來處理更少的線程。 –