System.Timers.Timer 奇怪的行为
System.Timers.Timer strange behaviour
这是一个代码。 运行 并立即按住 P。您应该两次看到第一次约会。我懂了。我真的不知道为什么会这样。我想了解一下。有人可以清楚地向我解释吗?
using System;
using System.Timers;
using System.Diagnostics;
namespace Timer1
{
class Program
{
static Stopwatch stopwatch = new Stopwatch();
static Timer timer;
static int interval = 1000;
static void Main(string[] args)
{
Console.SetBufferSize(1000, 1000);
timer = new Timer(interval);
timer.Elapsed += Function;
timer.Interval = interval;
timer.Enabled = true;
stopwatch.Start();
while (true)
{
ConsoleKey key = Console.ReadKey(true).Key;
if (key == ConsoleKey.P)
{
int temp = interval - (int)stopwatch.ElapsedMilliseconds;
if (temp > 0)
timer.Interval = temp;
else
Function(null, null);
}
else
{
timer.Dispose();
break;
}
Console.ReadKey(true);
}
}
static public void Function(object sender, EventArgs e)
{
timer.Interval = interval;
Console.WriteLine(DateTime.Now);
stopwatch.Reset();
stopwatch.Start();
}
}
}
根据您编写代码的方式,您有两条通往 Function() 的路径。一种方法是当计时器实际耗尽并且 Function() 结果为 "handled" 时。另一条路是when
interval - stopwatch.ElapsedMilliseconds
不大于0,此时直接调用Function()。
您似乎在使用 System.Timers.Timer。这是线程池线程上的 运行。由于您有多个线程 运行ning,因此两者都可以调用 Function()。您可能认为您通过在 Function() 中重置内部和秒表来防止这种情况发生,但是 Console.WriteLine() 足以允许一个线程延迟并让另一个线程 运行(在多处理器计算机上,两个线程可以在不同的处理器上同时 运行)。
根据您的逻辑性质,可以保证计时器间隔将在您的间隔测试达到 0 的几乎同时触发(调用处理程序),因此您可以预期它 运行 通过两条路径。
这个例子看起来不是很有用。是单纯的理解定时器吗?如果愿意,您可以更改时间间隔,但是当您将其大致更改为原来(或应该的)时,为什么还要费心呢?
这是一个代码。 运行 并立即按住 P。您应该两次看到第一次约会。我懂了。我真的不知道为什么会这样。我想了解一下。有人可以清楚地向我解释吗?
using System;
using System.Timers;
using System.Diagnostics;
namespace Timer1
{
class Program
{
static Stopwatch stopwatch = new Stopwatch();
static Timer timer;
static int interval = 1000;
static void Main(string[] args)
{
Console.SetBufferSize(1000, 1000);
timer = new Timer(interval);
timer.Elapsed += Function;
timer.Interval = interval;
timer.Enabled = true;
stopwatch.Start();
while (true)
{
ConsoleKey key = Console.ReadKey(true).Key;
if (key == ConsoleKey.P)
{
int temp = interval - (int)stopwatch.ElapsedMilliseconds;
if (temp > 0)
timer.Interval = temp;
else
Function(null, null);
}
else
{
timer.Dispose();
break;
}
Console.ReadKey(true);
}
}
static public void Function(object sender, EventArgs e)
{
timer.Interval = interval;
Console.WriteLine(DateTime.Now);
stopwatch.Reset();
stopwatch.Start();
}
}
}
根据您编写代码的方式,您有两条通往 Function() 的路径。一种方法是当计时器实际耗尽并且 Function() 结果为 "handled" 时。另一条路是when
interval - stopwatch.ElapsedMilliseconds
不大于0,此时直接调用Function()。
您似乎在使用 System.Timers.Timer。这是线程池线程上的 运行。由于您有多个线程 运行ning,因此两者都可以调用 Function()。您可能认为您通过在 Function() 中重置内部和秒表来防止这种情况发生,但是 Console.WriteLine() 足以允许一个线程延迟并让另一个线程 运行(在多处理器计算机上,两个线程可以在不同的处理器上同时 运行)。
根据您的逻辑性质,可以保证计时器间隔将在您的间隔测试达到 0 的几乎同时触发(调用处理程序),因此您可以预期它 运行 通过两条路径。
这个例子看起来不是很有用。是单纯的理解定时器吗?如果愿意,您可以更改时间间隔,但是当您将其大致更改为原来(或应该的)时,为什么还要费心呢?