7 ответов:
это очень хорошо, однако для того, чтобы имитировать некоторое время прохождения нам нужно запустить команду, которая занимает некоторое время, и это очень ясно во втором примере.
однако стиль использования цикла for для выполнения некоторых функций навсегда занимает много ресурсов устройства, и вместо этого мы можем использовать сборщик мусора, чтобы сделать что-то подобное.
мы можем увидеть эту модификацию в коде из той же книги CLR через 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(); } }
вот код для создания простого секундного таймера:
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:47EDIT: это никогда не хорошая идея, чтобы добавить жесткие спиновые петли в код, как они потребляют циклы процессора без выгоды. В этом случае этот цикл был добавлен только для того, чтобы остановить закрытие приложения, позволяя наблюдать за действиями потока. Но ради корректности и для уменьшения использования процессора был добавлен простой вызов сна эта петля.
давайте немного весело!--2-->
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(" B O O O O O M M M M M ! ! ! !"); Console.WriteLine(""); Console.WriteLine(" G A M E O V E R"); Console.WriteLine("=============================================="); timer.Close(); timer.Dispose(); } GC.Collect(); } } }
или с помощью Rx, короткий и сладкий:
static void Main() { Observable.Interval(TimeSpan.FromSeconds(10)).Subscribe(t => Console.WriteLine("I am called... {0}", t)); for (; ; ) { } }
вы также можете использовать свои собственные механизмы синхронизации, если вы хотите немного больше контроля, но меньше точности и больше кода/сложности, но я все равно рекомендую таймер. Используйте это, хотя, если вам нужно иметь контроль над фактическим потоком синхронизации:
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);обратный вызов-это ваш void parameterless метод, который вы хотите вызвать в каждом интервале. Например:
private void CallBack() { //Do Something. }
вы также можете создать свой собственный (если недовольны доступные варианты).
создание собственного
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);чтобы убедиться, что таймер работает, вы должны создать бесконечный цикл следующим образом:
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(); } }
Comments