【发布时间】:2017-06-17 12:32:18
【问题描述】:
因此,我正在尝试创建一种方法,该方法可以为窗体上的控件移动设置动画。我预先生成了控件将要到达的所有点,如下所示:
private static List<decimal> TSIncrement(int durationInMilliseconds, decimal startPoint, decimal endPoint)
{
List<decimal> tempPoints = new List<decimal>();
decimal distance = endPoint - startPoint;
decimal increment = distance / durationInMilliseconds;
decimal tempPoint = (decimal)startPoint;
for (decimal i = durationInMilliseconds; i > 0; i--)
{
tempPoint += increment;
tempPoints.Add(tempPoint);
}
return tempPoints;
}
这会输出一个列表,其中包含与动画持续时间中毫秒数一样多的点。我想你可以猜到我之后在做什么:
public static void ControlAnimation(Control control, Point locationEndpoint, int delay)
{
if (delay > 0)
{
List<decimal> tempXpoints = TSIncrement(delay, control.Location.X, locationEndpoint.X);
List<decimal> tempYpoints = TSIncrement(delay, control.Location.Y, locationEndpoint.Y);
for (int i = 0; i < delay; i++)
{
control.Location = new Point((int)Math.Round(tempXpoints[i]), (int)Math.Round(tempYpoints[i]));
Thread.Sleep(1); //I won't leave this obviously, it's just easier for now
}
}
}
在实际的方法中,我浏览了这个点列表并使用它们来创建控件的新位置(我实际上使用了两个列表作为横坐标和纵坐标)。
我的问题在于在每次换档之间产生一毫秒的延迟。由于循环中的代码需要一些时间来执行,所以我通常会多花大约 5 秒的时间。
我尝试使用秒表来测量设置 control.location 所需的时间,并将其减去 1 毫秒的延迟。秒表也增加了一些延迟,因为我每次都要开始、停止和重置它。
那么我应该怎么做,如何改进我的代码?非常感谢任何反馈:)
【问题讨论】:
-
不要依赖定时器回调/Thread.Sleep 的时间是否准确。它不是。启动一个(单个)秒表,然后使用
async和await Task.Delay()(或计时器,如果你是受虐狂,但绝对不是 Thread.Sleep) 导致短暂的延迟。当延迟结束时,找出已经过去了多少 实际 时间(通过检查 Stopwatch 实例),然后根据这个实际经过的时间值而不是由 wonky 导出的隐式累积时间值进行计算计时器。 -
谢谢@spender,我一定要试试这个。