C# Timer类

使用计时器,可以重复调用方法。我们将介绍两个计时器:System.Threading 名称空间中的 Timer 类和用于基于 XAML 应用程序的 DispatcherTimer。.

使用 System.Threading.Timer 类,可以把要调用的方法作为构造函数的第一个参数传递。这个方法必须满足 TimeCallback 委托的要求,该委托定义一个 void返回类型和一个 object 参数。通过构造函数的第二个参数,可以传递任意对象,用回调方法中的 object 参数接收对应的对象。例如,可以传递 Event 对象,向调用者发送信号。第 3 个参数指定第一次调用回调方法时的时间段。最后一个参数指定回调的重复时间间隔。如果计时器应只触发一次,就把第 4 个参数设置为值 -1。

如果创建 Timer 对象后应改变时间间隔,就可以用 Change() 方法传递新值:

private static void ThreadingTimer()
{
  void TimeAction (object o) =>
    Console.WriteLine($"System.Threading.Timer {DateTime.Now:T}");
    
  using (var t1 = new Timer(TimeAction, null,
    TimeSpan.FromSeconds(2),TimeSpan.FromSeconds(3)))
  {
    Task.Delay(15000).Wait();
  }
}

Windows.UI.Xaml 名称空间(用于 UWP 应用程)中的 DispatcherTimer 是一个基于 XAML 的应用程序的计时器,其中的事件处理程序在 UI 线程中调用,因此可以直接访问用户界面元素。

演示 DispatcherTimer 的示例应用程序是一个 Windows 应用程序,显示了切换每一秒的时钟指针。下面的 XAML 代码定义的命令允许开始和停止时钟:

<Page.TopAppBar>
  <CommandBar IsOpen="True">
    <AppBarButton Icon="Play" Click="{x:Bind OnTimer}" />
    <AppBarButton Icon="Stop" Click="{x:Bind OnStopTimer}" />
  </CommandBar>
</Page.TopAppBar>

时钟的指针使用形状 Line 定义。要旋转该指针,请使用 RotateTransform 元素:

<Canvas Width="300" Height="300">
  <Ellipse Width="10" Height="10" Fill="Red" Canvas.Left="145"
    Canvas.Top="145" />
  <Line Canvas.Left="150" Canvas.Top="150" Fill="Green" StrokeThickness="3"
    Stroke="Blue" X1="0" Y1="O" X2="120" Y2="O" >
    <Line.RenderTransform>
      <RotateTransform CenterX="0" CenterY="0" Angle="270" x:Name="rotate" />
    </Line.RenderTransform>
  </Line>
</Canvas>

DispatcherTimer 对象在 MainPage 类中创建。在构造数中,处理程方法分配给Tick 事件,Interval 指定为 1 秒。在 OnTimer 方法中启动计时器,该方法在用户单击 CommandBar 中的 Play 按钮时调用:

private DispatcherTimer _timer = new DispatcherTimer(); 
public MainPage()
{
  this.InitializeComponent();
  _timer.Tick += OnTick;
  _timer.Interval = TimeSpan.FromSeconds(1);
}

private void OnTimer() 
{
  _timer.Start();
}
private void OnTick(object sender, object e)
{
  double newAngle = rotate.Angle + 6;
  if (newAngle >= 360) newAngle = 0;
  rotate.Angle = newAngle;
}

private void OnStopTimer()
{
  _timer.Stop();
}