我有一个用户控件,以拨号格式显示速度(图像)。
它有一个方法:SetSpeed(int speed);
然后,从最后设定的速度开始,拨盘移动到所需的速度。它然后在实施中。也就是说,它会移动到新的速度。
问题是,如果汽车行驶速度为10km / h,然后(非常快)达到100km / h,则表盘可能需要2秒才能达到该速度......(这不是100%实时 - 这是是现实的..它移动到新的速度。)
但是,如果在拨号达到100km / h之前,这个人减速到50km / h,我需要将运动中断到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;
}
当我快速连续发送两个值时,它会锁定... 如果线程正在运行,如何中断线程并更改值?
(另外,我认为我改变速度的代码很糟糕 - 可以整理一下吗?)
答案 0 :(得分:1)
你没有。您可以通过适当的方式处理它,使用锁,并检查值是否需要更改。你不要打断它。
基本上,您需要SetSpeed和Refresh方法之间的锁定区域,以便阻止另一个。然后,当您设置速度并且线程当前处于关键区域时,它只是等待更新完成。
你的UpdateSpeed毫无意义 - 变化(空速 - 和空速++)应该是定时器驱动的...你当前以“任意”速度改变它们,这取决于处理器速度。没有时机。