56

我想从程序打开的那一刻起重复一个功能,直到它每隔几秒钟关闭一次。在 C# 中执行此操作的最佳方法是什么?

4

4 回答 4

82

使用计时器。有 3 种基本类型,每种都适用于不同的目的。

仅在 Windows 窗体应用程序中使用。此计时器作为消息循环的一部分进行处理,因此可以在高负载下冻结计时器。

当你需要同步时,使用这个。这意味着滴答事件将在启动计时器的线程上运行,让您可以毫不费力地执行 GUI 操作。

这是最强大的计时器,它在后台线程上触发滴答声。这使您可以在后台执行操作而无需冻结 GUI 或主线程。

对于大多数情况,我推荐 System.Timers.Timer。

于 2012-07-02T15:43:35.510 回答
46

为此,System.Timers.Timer效果最好

// Create a timer
myTimer = new System.Timers.Timer();
// Tell the timer what to do when it elapses
myTimer.Elapsed += new ElapsedEventHandler(myEvent);
// Set it to go off every five seconds
myTimer.Interval = 5000;
// And start it        
myTimer.Enabled = true;

// Implement a call with the right signature for events going off
private void myEvent(object source, ElapsedEventArgs e) { }

有关详细信息,请参阅计时器类(.NET 4.6 和 4.5)

于 2012-07-02T16:15:40.313 回答
10

使用计时器。请记住,.NET 带有许多不同的计时器。本文介绍了这些差异。

于 2012-07-02T15:43:15.820 回答
3

.NET BCL 中有很多不同的计时器:

什么时候用哪个?

  • System.Timers.Timer,它触发一个事件并定期在一个或多个事件接收器中执行代码。该类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。
  • System.Threading.Timer,它定期在线程池线程上执行单个回调方法。回调方法是在定时器实例化时定义的,不能更改。与 System.Timers.Timer 类一样,此类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。
  • System.Windows.Forms.Timer(仅限 .NET Framework),一种 Windows 窗体组件,它触发一个事件并定期在一个或多个事件接收器中执行代码。该组件没有用户界面,设计用于单线程环境;它在 UI 线程上执行。
  • System.Web.UI.Timer(仅限 .NET Framework),一个 ASP.NET 组件,它定期执行异步或同步网页回发。
  • System.Windows.Threading.DispatcherTimer,一个集成到 Dispatcher 队列中的计时器。该计时器以指定的时间间隔以指定的优先级进行处理。

来源


其中一些需要显式Start调用才能开始计时(例如System.Timers, System.Windows.Forms)。并明确Stop完成滴答。

using TimersTimer = System.Timers.Timer;

static void Main(string[] args)
{
    var timer = new TimersTimer(1000);
    timer.Elapsed += (s, e) => Console.WriteLine("Beep");
    Thread.Sleep(1000); //1 second delay
    timer.Start();
    Console.ReadLine();
    timer.Stop();

}

另一方面,有一些计时器(例如:)System.Threading,您不需要显式StartStop调用。(提供的委托将运行一个后台线程。)您的计时器将计时,直到您或运行时处理它。

因此,以下两个版本将以相同的方式工作:

using ThreadingTimer = System.Threading.Timer;

static void Main(string[] args)
{
    var timer = new ThreadingTimer(_ => Console.WriteLine("Beep"), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
    Console.ReadLine();
}
using ThreadingTimer = System.Threading.Timer;
static void Main(string[] args)
{
    StartTimer();
    Console.ReadLine();
}

static void StartTimer()
{
    var timer = new ThreadingTimer(_ => Console.WriteLine("Beep"), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}

但是,如果您timer处置,那么它显然会停止滴答作响。

using ThreadingTimer = System.Threading.Timer; 

static void Main(string[] args)
{
    StartTimer();
    GC.Collect(0);
    Console.ReadLine();
}

static void StartTimer()
{
    var timer = new ThreadingTimer(_ => Console.WriteLine("Beep"), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}
于 2020-12-04T14:46:27.880 回答