在线程中使用秒表的问题

本文关键字:问题 线程 | 更新日期: 2023-09-27 18:13:22

我有一个函数,它应该每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是一个抽象类的方法,我从抽象类创建了一个派生类,以这种方式实现了这个函数:

[....]
int Damage { get; private set; }
[....]   
protected override void ApplyTick(IUnit unit)
{
    Damage += 5;
}

在第一段代码(只是卡住线程直到持续时间通过)之后发生的事情是调试打印中显示的数字大于100000,其中基本值为10。

当我改变到线程方法时,同样的事情发生了,只是数字变大了,
它没有让游戏线程卡住。

为了解决这个问题,我选择了一种不同的方式,使用线程。睡眠

private void ThreadMethod(IUnit unit)
{
    int timeWaited = 0;
    int sleepTime = int.Parse(TickTime.ToString());
    while (timeWaited < Duration)
    {
        Thread.Sleep(sleepTime);
        ApplyTick(unit);
        timeWaited += sleepTime;
    }
}

这确实解决了问题,但我觉得如果
最终会出错我使用线程。睡觉而不是用秒表。有谁能解释一下,当我使用秒表时,为什么会发生这种情况?

在线程中使用秒表的问题

通过从

更改if来解决问题
if (Timer.ElapsedMilliseconds % TickTime == 0)

if (Timer.Elapsed.TotalMilliseconds % TickTime == 0)

为什么它工作?我不知道。
好像是秒表。ElapsedMilliseconds应该返回保存值为fooStopwatch.Elapsed.TotalMilliseconds,但事实并非如此。