所以我正在制作一个抢劫系统,计时器在第一次启动时工作完美,计时器下降的顺序是10,9,8,7 ......但是在第二次尝试时序列是10,8 ,6,4 ...... 3日尝试其10,7,4,1 ..... Etc意味着每次启动定时器序列增加减少时间?这怎么可能?你可以为我编代码吗?
public int time;
Timer cd = new Timer(2000);
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);
}
但是当我在OnTimer上使用(cd1.Elapsed += (Object source, ElapsedEventArgs e, User player)
时,它在cd.Elapsed -= (source, e) => OnTimer(source, e, player);
行上给出了一个错误,说明局部变量是源不能在这里使用,因为它在此范围内定义
答案 0 :(得分:2)
我怀疑这是因为你的经过事件处理程序实际上并没有被移除,所以它在每次打勾时都会多次触发。
以下问题/答案讨论了如何删除委托,以及Delegate.Equals如何确定删除哪个委托(如果有):C# removing an event handler
但是,您没有删除相同的处理程序,而是创建两个单独的lambda函数,这些函数在不同的上下文中执行完全相同的任务。 .NET不能很好地折叠重复的代码 - 它无法解决你的第二个lambda与你的第一个lambda相同的原因,因为它们都是在不同的范围内创建的,因此每个lambda都有一个不同的闭包(所有可见变量的保存图像)在其创建的范围内。)
如果你创建一个实际的非lambda方法,然后使用委托而不是lambdas,这个问题应该消失。或者,您可以将lambda分配给两个函数都可以访问的变量(不需要在它们之间进行修改)。
答案 1 :(得分:0)
这是Matt Jordan's solution的示例实现“将lambda分配给两个函数都可以访问的变量”
public int time;
Timer cd = new Timer(2000);
public void robberyCountdown(User player)
{
time = 10;
ElapsedEventHandler handler = null;
handler = (source, e) => OnTimer(player, handler);
cd.Elapsed += handler;
cd.Start();
}
public void OnTimer(User player, ElapsedEventHandler handler)
{
cd.Stop();
cd.Elapsed -= handler;
}
因为lambadas捕获变量而非值,handler
可以引用自身,只要它在您尝试使用它之前已经初始化为值(在此示例中为null
)。