C# 计时器顺序搞砸了

C# 计时器顺序搞砸了,c#,timer,C#,Timer,因此,我正在制作一个抢劫系统计时器在第一次启动时工作正常,但在第二次尝试时,它会缩短时间2秒。。这意味着计时器的顺序是10,9,8,7。。。。。。但在第二次尝试时,顺序是10,8,6,4。。。。。。在第三次尝试它的10,7,4,1。。。。。Etc意味着每次启动定时器序列都会增加减少时间?怎么可能呢 public void robberyCountdown(User player) { time = 10; cd.Elapsed += (source, e) => OnTim

因此,我正在制作一个抢劫系统计时器在第一次启动时工作正常,但在第二次尝试时,它会缩短时间2秒。。这意味着计时器的顺序是10,9,8,7。。。。。。但在第二次尝试时,顺序是10,8,6,4。。。。。。在第三次尝试它的10,7,4,1。。。。。Etc意味着每次启动定时器序列都会增加减少时间?怎么可能呢

public void robberyCountdown(User player)
{
    time = 10;
    cd.Elapsed += (source, e) => OnTimer(player);
    cd.Start();
}

public void OnTimer(User player)
{
    cd.Stop();
    cd.Elapsed -= (source, e) => OnTimer(player);
}     

将创建的代理保存到专用字段中,以便以后可以访问它:

private ElapsedEventHandler _onTimer;

public void robberyCountdown(User player)
{
    time = 10;
    _onTimer = (source, e) => OnTimer(player)
    cd.Elapsed += _onTimer;
    cd.Start();
}

public void OnTimer(User player)
{
    cd.Stop();
    cd.Elapsed -= _onTimer;
}     
当然,这种方法假设
player
对两者都是相同的。一个更好的方法可能是让您的代理保持不变,并使用一个私有字段来跟踪正在计时的玩家

private HashSet<Player> _timedPlayers = new HashSet<Player>();

public MyClass() // or whatever your constructor is called
{
    cd.Elapsed += OnTimer;
}

public void OnTimer(Object source, ElapsedEventArgs e)
{
    foreach(var player in _timedPlayers)
    {
        // ...
    }
}

public void robberyCountdown(User player)
{
    time = 10;
    _timedPlayers.Add(player);
    cd.Start();
}

public void OnTimer(User player)
{
    cd.Stop();
    _timedPlayers.Remove(player);
}     
private HashSet\u timedPlayers=new HashSet();
public MyClass()//或调用构造函数的任何内容
{
cd.已用时间+=OnTimer;
}
public void OnTimer(对象源,ElapsedEventArgs e)
{
foreach(在_timedPlayers中的var播放器)
{
// ...
}
}
公共无效robberyCountdown(用户玩家)
{
时间=10;
_添加(播放器);
cd.Start();
}
公用void OnTimer(用户播放器)
{
cd.Stop();
_移除(玩家);
}     

将您创建的代理保存到一个专用字段中,以便您以后可以访问它:

private ElapsedEventHandler _onTimer;

public void robberyCountdown(User player)
{
    time = 10;
    _onTimer = (source, e) => OnTimer(player)
    cd.Elapsed += _onTimer;
    cd.Start();
}

public void OnTimer(User player)
{
    cd.Stop();
    cd.Elapsed -= _onTimer;
}     
当然,这种方法假设
player
对两者都是相同的。一个更好的方法可能是让您的代理保持不变,并使用一个私有字段来跟踪正在计时的玩家

private HashSet<Player> _timedPlayers = new HashSet<Player>();

public MyClass() // or whatever your constructor is called
{
    cd.Elapsed += OnTimer;
}

public void OnTimer(Object source, ElapsedEventArgs e)
{
    foreach(var player in _timedPlayers)
    {
        // ...
    }
}

public void robberyCountdown(User player)
{
    time = 10;
    _timedPlayers.Add(player);
    cd.Start();
}

public void OnTimer(User player)
{
    cd.Stop();
    _timedPlayers.Remove(player);
}     
private HashSet\u timedPlayers=new HashSet();
public MyClass()//或调用构造函数的任何内容
{
cd.已用时间+=OnTimer;
}
public void OnTimer(对象源,ElapsedEventArgs e)
{
foreach(在_timedPlayers中的var播放器)
{
// ...
}
}
公共无效robberyCountdown(用户玩家)
{
时间=10;
_添加(播放器);
cd.Start();
}
公用void OnTimer(用户播放器)
{
cd.Stop();
_移除(玩家);
}     

删除事件处理程序的方式不起作用。它不知道您试图删除的代理与您添加的代理等效。。。如果希望删除委托,则必须将其存储在变量中。或者,你可以从中找到一个合适的方法。因此,您当前拥有的是多个正在添加的
已用
处理程序,而没有一个被删除。此外,如果您从未实际使用其他事件处理程序,只需在类初始化中设置一次,在启动和停止时不必担心从计时器中添加/删除它。您将匿名函数传递给eventhandler,因此实际上不会删除它。尝试将
OnTimer
方法的定义更改为事件
(发送者,源)
。但是当我在OnTimer上使用(cd1.appeased+=(对象源,ElapsedEventArgs e,用户播放器)时,它会在cd上给我一个错误。appeased-=(源,e)=>OnTimer(源,e,播放器);此处不能使用说明局部变量为源的行,因为它是在此范围内定义的。您删除事件处理程序的方式不起作用。它不知道您尝试删除的委托与您添加的委托等效…如果希望删除委托,您必须将其存储在变量中。或者,您可以使用适当的方法此外,如果您从未实际使用过其他事件处理程序,则只需在类初始化中设置一次,并且在启动和停止时不必担心从计时器中添加/删除它。您正在将匿名函数传递给t事件处理程序,因此它实际上没有被删除。请尝试将
OnTimer
方法的定义更改为事件
(发件人,源代码)
。但是当我在OnTimer上使用(cd1.appeased+=(Object source,ElapsedEventArgs e,User player)时,它会在cd上给我一个错误。appeased-=(source,e)=>OnTimer(source,e,player);说明局部变量是源的行在此不能使用,因为它在此范围中定义。iget此错误出现在cd的语句中。已用+=\u onTimer;无法将类型“System.EventHandler”隐式转换为“System.Timers.ElapsedEventHandler”\u onTimer有一条红线,表示我希望该方法假定它适用于同一播放器。igetcd.Epersed+=\u onTimer;语句中的此错误无法将类型“System.EventHandler”隐式转换为“System.Timers.ElapsedEventHandler”\u onTimer有一条红线,表示我希望该方法假定它适用于同一播放器。