如何将计时器添加到C#控制台应用程序
只是这 – 如何添加一个计时器到C#控制台应用程序? 如果您可以提供一些示例编码,那将是非常好的。
这是非常好的,但是为了模拟一段时间,我们需要运行一个需要一些时间的命令,在第二个例子中这是非常清楚的。
然而,使用for循环永远做一些function的风格需要大量的设备资源,相反,我们可以使用垃圾收集器来做一些这样的事情。
我们可以从同一本书CLR Via C#Third Ed的代码中看到这种修改。
using System; using System.Threading; public static class Program { public static void Main() { // Create a Timer object that knows to call our TimerCallback // method once every 2000 milliseconds. Timer t = new Timer(TimerCallback, null, 0, 2000); // Wait for the user to hit <Enter> Console.ReadLine(); } private static void TimerCallback(Object o) { // Display the date/time when this method got called. Console.WriteLine("In TimerCallback: " + DateTime.Now); // Force a garbage collection to occur for this demo. GC.Collect(); } }
使用System.Threading.Timer类。
System.Windows.Forms.Timer主要用于单个线程,通常是Windows窗体UI线程。
在.NET框架的开发中,还有一个System.Timers类。 但是一般build议使用System.Threading.Timer类,因为这只是System.Threading.Timer的一个包装。
如果您正在开发Windows服务并需要定时器定期运行,则还build议始终使用静态(在VB.NET中共享)System.Threading.Timer。 这将避免可能过早垃圾收集您的计时器对象。
这里是一个控制台应用程序中的计时器的例子:
using System; using System.Threading; public static class Program { public static void Main() { Console.WriteLine("Main thread: starting a timer"); Timer t = new Timer(ComputeBoundOp, 5, 0, 2000); Console.WriteLine("Main thread: Doing other work here..."); Thread.Sleep(10000); // Simulating other work (10 seconds) t.Dispose(); // Cancel the timer now } // This method's signature must match the TimerCallback delegate private static void ComputeBoundOp(Object state) { // This method is executed by a thread pool thread Console.WriteLine("In ComputeBoundOp: state={0}", state); Thread.Sleep(1000); // Simulates other work (1 second) // When this method returns, the thread goes back // to the pool and waits for another task } }
来自Jeff Richter的CLR Via C# 。 顺便说一下,这本书在第23章中描述了三类定时器的基本原理,强烈推荐。
这里是创build一个简单的一秒计时器代码的代码:
using System; using System.Threading; class TimerExample { static public void Tick(Object stateInfo) { Console.WriteLine("Tick: {0}", DateTime.Now.ToString("h:mm:ss")); } static void Main() { TimerCallback callback = new TimerCallback(Tick); Console.WriteLine("Creating timer: {0}\n", DateTime.Now.ToString("h:mm:ss")); // create a one second timer tick Timer stateTimer = new Timer(callback, null, 0, 1000); // loop here forever for (; ; ) { // add a sleep for 100 mSec to reduce CPU usage Thread.Sleep(100); } } }
这里是结果输出:
c:\temp>timer.exe Creating timer: 5:22:40 Tick: 5:22:40 Tick: 5:22:41 Tick: 5:22:42 Tick: 5:22:43 Tick: 5:22:44 Tick: 5:22:45 Tick: 5:22:46 Tick: 5:22:47
编辑:这是永远不会是一个好主意,因为他们消耗CPU周期没有增益的硬循环代码。 在这种情况下,添加循环只是为了阻止应用程序closures,允许观察线程的操作。 但是为了正确性和降低CPU使用率,简单的Sleep调用被添加到该循环中。
或者使用Rx,简短而甜美:
static void Main() { Observable.Interval(TimeSpan.FromSeconds(10)).Subscribe(t => Console.WriteLine("I am called... {0}", t)); for (; ; ) { } }
让我们有一点乐趣
using System; using System.Timers; namespace TimerExample { class Program { static Timer timer = new Timer(1000); static int i = 10; static void Main(string[] args) { timer.Elapsed+=timer_Elapsed; timer.Start(); Console.Read(); } private static void timer_Elapsed(object sender, ElapsedEventArgs e) { i--; Console.Clear(); Console.WriteLine("================================================="); Console.WriteLine(" DIFFUSE THE BOMB"); Console.WriteLine(""); Console.WriteLine(" Time Remaining: " + i.ToString()); Console.WriteLine(""); Console.WriteLine("================================================="); if (i == 0) { Console.Clear(); Console.WriteLine(""); Console.WriteLine("=============================================="); Console.WriteLine(" BOOOOOMMMMM ! ! ! !"); Console.WriteLine(""); Console.WriteLine(" GAMEOVER"); Console.WriteLine("=============================================="); timer.Close(); timer.Dispose(); } GC.Collect(); } } }
你也可以使用自己的时间机制,如果你想多一点控制,但可能不太准确,更多的代码/复杂性,但我仍然会推荐一个计时器。 尽pipe如此,如果你需要控制实际的时间线程:
private void ThreadLoop(object callback) { while(true) { ((Delegate) callback).DynamicInvoke(null); Thread.Sleep(5000); } }
将是你的计时线程(修改这个停止当reqiuired,并在任何时间间隔,你想)。
并使用/启动你可以这样做:
Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop)); t.Start((Action)CallBack);
callback是你想要在每个时间间隔调用的无效无参数方法。 例如:
private void CallBack() { //Do Something. }
您也可以创build自己的(如果对可用选项不满意)。
创build你自己的Timer
实现是非常基本的东西。
这是一个需要在我的代码库的其余部分在同一个线程上访问COM对象的应用程序的例子。
/// <summary> /// Internal timer for window.setTimeout() and window.setInterval(). /// This is to ensure that async calls always run on the same thread. /// </summary> public class Timer : IDisposable { public void Tick() { if (Enabled && Environment.TickCount >= nextTick) { Callback.Invoke(this, null); nextTick = Environment.TickCount + Interval; } } private int nextTick = 0; public void Start() { this.Enabled = true; Interval = interval; } public void Stop() { this.Enabled = false; } public event EventHandler Callback; public bool Enabled = false; private int interval = 1000; public int Interval { get { return interval; } set { interval = value; nextTick = Environment.TickCount + interval; } } public void Dispose() { this.Callback = null; this.Stop(); } }
您可以添加事件如下:
Timer timer = new Timer(); timer.Callback += delegate { if (once) { timer.Enabled = false; } Callback.execute(callbackId, args); }; timer.Enabled = true; timer.Interval = ms; timer.Start(); Window.timers.Add(Environment.TickCount, timer);
为了确保定时器的工作,你需要创build一个无限循环,如下所示:
while (true) { // Create a new list in case a new timer // is added/removed during a callback. foreach (Timer timer in new List<Timer>(timers.Values)) { timer.Tick(); } }