0

我有一个用户控件,它以拨号格式(图像)显示速度。

它有一个方法:SetSpeed(int speed);

然后它使转盘从最后设定的速度移动到所需的速度。然后它会加罪。也就是说,它移动到新的速度。

问题是,如果汽车以 10 公里/小时的速度行驶,然后(非常快地)达到 100 公里/小时,则表盘可能需要 2 秒才能达到该速度......(这不是 100% 实时 - 这是现实的。 . 它移动到新的速度)。

但是,如果在表盘达到 100 公里/小时之前,人减速到 50 公里/小时,我需要中断移动到 100,然后开始移动到 50。不管表盘的当前位置(而不是速度)如何,我需要更改“目标速度”。

我的控件使用 BackgroundWorker 来处理刷新,而不是锁定 UI。

所以,我的电话在 UI 上是非常基本的:

dial1.SetSpeed(int.Parse(value));

然后用户控件执行此操作:

BackgroundWorker bw = new BackgroundWorker();

public void SetSpeed(int speed)
        {
            while(bw.IsBusy)
            {
                Thread.Sleep(50);
            }
            bw.RunWorkerAsync(speed);
        }

以及完成工作的方法:

private void UpdateSpeed(object sender, DoWorkEventArgs e)
        {
            var oldSpeed = airSpeed;
            var newSpeed = (int) e.Argument;


            if(oldSpeed <= newSpeed)
            {
                for (int i = oldSpeed; i < newSpeed; i++)
                {
                    airSpeed++;
                    this.Invoke(new MethodInvoker(Refresh));
                }
            }
            else
            {
                for (int i = oldSpeed; i > newSpeed; i--)
                {
                    airSpeed--;
                    this.Invoke(new MethodInvoker(Refresh));

                }

            }
            airSpeed = newSpeed;
        }

当我快速连续发送两个值时它会锁定......如果线程正在运行,我如何中断线程并更改值?

(另外,我认为我改变速度的代码很糟糕 - 可以做得更整洁吗?)

4

1 回答 1

1

你不。您以适当的方式处理它,使用锁,并检查值是否需要更改。你不要打断它。

基本上,您需要在 SetSpeed 和 Refresh 方法之间设置一个锁定区域,以便一个阻止另一个。然后,当您设置速度并且线程当前处于关键区域时,它只是等待更新完成。

而且您的 UpdateSpeed 毫无意义 - 更改(空速 - 和空速 ++)应该是计时器驱动的......您目前以“任意”速度更改它们,具体取决于处理器速度。没有时间。

于 2013-01-07T08:04:00.843 回答