Dispatcher没有出现在类中 - 使用System.Threading.Timer

时间:2016-05-13 07:48:25

标签: c# wpf multithreading

我正在使用WPF为计算机科学项目创建一个节奏游戏(不像吉他英雄那样下降的游戏 - 但带箭头)并且遇到了一些性能问题。我使用了很多DispatcherTimers,这会降低应用程序的速度并使其冻结。为了解决这个问题,我找到了answer,建议使用System.Threading.Timers。

据我所知,通过使用这个,我为这些计时器创建了新的线程,允许它们同时运行,而不会使应用程序的速度降低到可怕的速度。

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

    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,右箭头为第二等)并向其Y添加一定数量在将新位置设置到画布之前进行坐标。

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

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

1 个答案:

答案 0 :(得分:0)

最后,我通过采用了很多'ArrowFall'方法并将它们全部合二为一,取出了几个计时器并使我的代码更有效率。到那时,调度员使用较少的计时器,我没有错误。由于我不知道究竟是什么原因引起了问题,我想我最终还是以某种方式解决了这个问题。