Только это - Как добавить таймер в консольное приложение C#? Было бы здорово, если бы вы могли предоставить примерное кодирование.Как добавить таймер в консольное приложение C#
ответ
Это очень хорошо, однако для того, чтобы симулировать какое-то время прохождения нам нужно запустить команду, которая занимает некоторое время, и это очень ясно, во втором примере.
Однако стиль использования цикла for для выполнения некоторых функций навсегда занимает много ресурсов устройства, и вместо этого мы можем использовать сборщик мусора, чтобы сделать что-то подобное.
Мы можем видеть это изменение в кодексе из той же книги 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 Forms.
В начале разработки .NET Framework также появился класс System.Timers. Однако обычно рекомендуется использовать класс System.Threading.Timer, поскольку это всего лишь обертка вокруг System.Threading.Timer.
Также рекомендуется всегда использовать статический (совместно используемый в VB.NET) System.Threading.Timer, если вы разрабатываете службу Windows и требуете, чтобы таймер запускался периодически. Это позволит избежать возможной преждевременной сборки мусора вашего объекта таймера.
Вот пример таймера в консольном приложении:
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
}
}
Из книги CLR Via C# Джеффа Рихтера. Кстати, эта книга описывает обоснование трех типов таймеров в главе 23, настоятельно рекомендуется.
Можете ли вы предоставить немного больше информации о фактическом кодировании? – 2008-10-09 06:12:21
Использует ли пример из msdn для вас? http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx – 2008-10-09 06:15:59
Эрик, я не пробовал, но не было бы необычным, если бы была проблема с ним. Я замечаю, что он также пытается сделать какую-то межпоточную синхронизацию, это всегда область, которая может быть сложной, чтобы получить право. Если вы можете избежать этого в своем дизайне, всегда разумно это делать. – Ash 2008-10-09 06:29:54
Вот код, чтобы создать простую клеща один второй таймер:
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
EDIT: Это никогда не является хорошей идеей, чтобы добавить жесткие циклы вращения в код, поскольку они потребляют циклы процессора без усиления. В этом случае этот цикл был добавлен только для того, чтобы остановить закрытие приложения, позволяя наблюдать действия потока. Но ради правильности и сокращения использования ЦП в этот цикл был добавлен простой вызов сна.
Функция for (;;) {} вызывает 100% -ное использование процессора. – 2012-12-21 16:36:05
Вы также можете использовать свои собственные механизмы синхронизации, если хотите немного больше контроля, но, возможно, меньше точности и большего количества кода/сложности, но я бы по-прежнему рекомендовал таймер. Используйте это, хотя, если вам нужно иметь контроль над фактической нитью синхронизации:
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);
Ответный Ваш аннулируются метод без параметров, который вы хотите назвать в каждом интервале. Например:
private void CallBack()
{
//Do Something.
}
Или с помощью Rx, коротким и сладким:
static void Main()
{
Observable.Interval(TimeSpan.FromSeconds(10)).Subscribe(t => Console.WriteLine("I am called... {0}", t));
for (; ;) { }
}
Вы также можете создавать свои собственные (если несчастна с доступными опциями).
Создание собственного решения 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();
}
}
Позволяет немного развлечься
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();
}
}
}
Предупреждение: ответы здесь имеют ошибка, объект Timer собирается собирать мусор. Ссылка на таймер должна храниться в статической переменной, чтобы обеспечить сохранение тикания. – 2014-12-14 21:45:47