在线程中使用秒表的问题
Issues with using Stopwatch in a thread
我有一个函数应该每隔 X 秒发生一次,直到 Y 秒过去。
有一个 long TickTime;
和 long Duration;
变量,以及一个应该计算时间的 Stopwatch 对象。
起初,运行 的方法是这样的:
public override bool ApplyBehavior(IUnit unit)
{
Timer.Start();
while (Timer.ElapsedMilliseconds < Duration)
if (Timer.ElapsedMilliseconds % TickTime == 0)
ApplyTick(unit);
Timer.Stop();
return true;
}
发生的事情是 while
刚刚接管了游戏 运行 的线程,所以我将其拆分为:
public override bool ApplyBehavior(IUnit unit)
{
Thread trd = new Thread(() => ThreadMethod(unit));
trd.Start();
return true;
}
private void ThreadMethod(IUnit unit)
{
Timer.Start();
while (Timer.ElapsedMilliseconds < Duration)
if (Timer.ElapsedMilliseconds % TickTime == 0)
ApplyTick(unit);
Timer.Stop();
}
ApplyTick 是抽象方法 class,我从中创建了一个派生的 class,它以这种方式实现了函数:
[....]
int Damage { get; private set; }
[....]
protected override void ApplyTick(IUnit unit)
{
Damage += 5;
}
在第一段代码(将线程卡住直到持续时间过去)之后发生的事情是调试打印中显示的数字高于 100000,其中基值为 10。
当我改用线程方法时,同样的事情发生了,只是数字变大了
它没有让游戏线程卡住。
为了解决这个问题,我选择了另一种方式,使用 Thread.Sleep
private void ThreadMethod(IUnit unit)
{
int timeWaited = 0;
int sleepTime = int.Parse(TickTime.ToString());
while (timeWaited < Duration)
{
Thread.Sleep(sleepTime);
ApplyTick(unit);
timeWaited += sleepTime;
}
}
这确实解决了问题,但我觉得如果
最终会出问题
我使用 thread.sleep 而不是秒表。
谁能解释为什么我使用秒表时会发生这种情况?
通过从
更改 if 解决了问题
if (Timer.ElapsedMilliseconds % TickTime == 0)
至
if (Timer.Elapsed.TotalMilliseconds % TickTime == 0)
为什么有效?我不知道。
似乎 fooStopwatch.ElapsedMilliseconds 应该 return 将值保存为 fooStopwatch.Elapsed.TotalMilliseconds 但事实并非如此。
我有一个函数应该每隔 X 秒发生一次,直到 Y 秒过去。
有一个 long TickTime;
和 long Duration;
变量,以及一个应该计算时间的 Stopwatch 对象。
起初,运行 的方法是这样的:
public override bool ApplyBehavior(IUnit unit)
{
Timer.Start();
while (Timer.ElapsedMilliseconds < Duration)
if (Timer.ElapsedMilliseconds % TickTime == 0)
ApplyTick(unit);
Timer.Stop();
return true;
}
发生的事情是 while
刚刚接管了游戏 运行 的线程,所以我将其拆分为:
public override bool ApplyBehavior(IUnit unit)
{
Thread trd = new Thread(() => ThreadMethod(unit));
trd.Start();
return true;
}
private void ThreadMethod(IUnit unit)
{
Timer.Start();
while (Timer.ElapsedMilliseconds < Duration)
if (Timer.ElapsedMilliseconds % TickTime == 0)
ApplyTick(unit);
Timer.Stop();
}
ApplyTick 是抽象方法 class,我从中创建了一个派生的 class,它以这种方式实现了函数:
[....]
int Damage { get; private set; }
[....]
protected override void ApplyTick(IUnit unit)
{
Damage += 5;
}
在第一段代码(将线程卡住直到持续时间过去)之后发生的事情是调试打印中显示的数字高于 100000,其中基值为 10。
当我改用线程方法时,同样的事情发生了,只是数字变大了
它没有让游戏线程卡住。
为了解决这个问题,我选择了另一种方式,使用 Thread.Sleep
private void ThreadMethod(IUnit unit)
{
int timeWaited = 0;
int sleepTime = int.Parse(TickTime.ToString());
while (timeWaited < Duration)
{
Thread.Sleep(sleepTime);
ApplyTick(unit);
timeWaited += sleepTime;
}
}
这确实解决了问题,但我觉得如果
最终会出问题
我使用 thread.sleep 而不是秒表。
谁能解释为什么我使用秒表时会发生这种情况?
通过从
更改 if 解决了问题if (Timer.ElapsedMilliseconds % TickTime == 0)
至
if (Timer.Elapsed.TotalMilliseconds % TickTime == 0)
为什么有效?我不知道。
似乎 fooStopwatch.ElapsedMilliseconds 应该 return 将值保存为 fooStopwatch.Elapsed.TotalMilliseconds 但事实并非如此。