Hanya ini - Bagaimana Anda menambahkan timer ke aplikasi konsol C #? Akan lebih bagus jika Anda bisa menyediakan beberapa contoh pengkodean.
Hanya ini - Bagaimana Anda menambahkan timer ke aplikasi konsol C #? Akan lebih bagus jika Anda bisa menyediakan beberapa contoh pengkodean.
Jawaban:
Itu sangat bagus, namun untuk mensimulasikan beberapa waktu yang berlalu kita perlu menjalankan perintah yang membutuhkan waktu dan itu sangat jelas dalam contoh kedua.
Namun, gaya menggunakan loop untuk melakukan beberapa fungsi selamanya membutuhkan banyak sumber daya perangkat dan sebagai gantinya kita dapat menggunakan Pengumpul Sampah untuk melakukan hal seperti itu.
Kita dapat melihat modifikasi ini dalam kode dari buku yang sama 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();
}
}
GC.Collect()
. Tidak ada yang dikumpulkan. Akan masuk akal, jika GC.KeepAlive(t)
dipanggil setelahConsole.ReadLine();
Gunakan kelas System.Threading.Timer.
System.Windows.Forms.Timer dirancang terutama untuk digunakan dalam utas tunggal biasanya utas Windows Forms UI.
Ada juga kelas System.Timers ditambahkan sejak awal dalam pengembangan kerangka NET. Namun umumnya disarankan untuk menggunakan kelas System.Threading.Timer sebagai gantinya ini hanya pembungkus di sekitar System.Threading.Timer saja.
Dianjurkan juga untuk selalu menggunakan Sistem statis (dibagi dalam VB.NET) System.Threading.Timer jika Anda mengembangkan Layanan Windows dan memerlukan timer untuk berjalan secara berkala. Ini akan menghindari kemungkinan pengumpulan sampah prematur dari objek pengatur waktu Anda.
Berikut ini contoh penghitung waktu di aplikasi konsol:
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
}
}
Dari buku CLR Via C # oleh Jeff Richter. Ngomong-ngomong buku ini menggambarkan alasan di balik 3 jenis penghitung waktu di Bab 23, sangat dianjurkan.
Berikut adalah kode untuk membuat centang satu detik sederhana:
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);
}
}
}
Dan inilah output yang dihasilkan:
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: Tidak pernah merupakan ide yang baik untuk menambahkan hard spin loop ke dalam kode karena mereka mengkonsumsi siklus CPU tanpa hasil. Dalam hal ini, loop ditambahkan hanya untuk menghentikan aplikasi agar tidak menutup, sehingga tindakan dari thread dapat diamati. Tetapi demi kebenaran dan untuk mengurangi penggunaan CPU panggilan Sleep sederhana telah ditambahkan ke loop itu.
Mari Bersenang-senang
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(" DEFUSE 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();
}
}
}
Atau menggunakan Rx, pendek dan manis:
static void Main()
{
Observable.Interval(TimeSpan.FromSeconds(10)).Subscribe(t => Console.WriteLine("I am called... {0}", t));
for (; ; ) { }
}
Anda juga dapat menggunakan mekanisme pengaturan waktu Anda sendiri jika Anda ingin sedikit lebih banyak kontrol, tetapi mungkin kurang akurat dan lebih banyak kode / kompleksitas, tetapi saya masih akan merekomendasikan timer. Gunakan ini meskipun jika Anda harus memiliki kontrol atas utas waktu aktual:
private void ThreadLoop(object callback)
{
while(true)
{
((Delegate) callback).DynamicInvoke(null);
Thread.Sleep(5000);
}
}
akan menjadi utas waktu Anda (modifikasi ini untuk berhenti ketika diperlukan, dan pada interval waktu apa pun yang Anda inginkan).
dan untuk menggunakan / memulai Anda dapat melakukan:
Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop));
t.Start((Action)CallBack);
Callback adalah metode tanpa parameter kosong yang ingin Anda panggil pada setiap interval. Sebagai contoh:
private void CallBack()
{
//Do Something.
}
Anda juga dapat membuat sendiri (jika tidak puas dengan opsi yang tersedia).
Membuat Timer
implementasi Anda sendiri adalah hal yang cukup mendasar.
Ini adalah contoh untuk aplikasi yang membutuhkan akses objek COM pada utas yang sama dengan sisa basis kode saya.
/// <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();
}
}
Anda dapat menambahkan acara sebagai berikut:
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);
Untuk memastikan timer berfungsi, Anda perlu membuat loop tanpa akhir sebagai berikut:
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();
}
}
Itu dia :)
public static void Main()
{
SetTimer();
Console.WriteLine("\nPress the Enter key to exit the application...\n");
Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
Console.ReadLine();
aTimer.Stop();
aTimer.Dispose();
Console.WriteLine("Terminating the application...");
}
private static void SetTimer()
{
// Create a timer with a two second interval.
aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
e.SignalTime);
}
Saya sarankan Anda mengikuti pedoman Microsoft ( https://docs.microsoft.com/en-us/dotnet/api/system.timers.timer.interval?view=netcore-3.1 ).
Saya pertama kali mencoba menggunakan System.Threading;
dengan
var myTimer = new Timer((e) =>
{
// Code
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
tetapi terus berhenti setelah ~ 20 menit.
Dengan itu, saya mencoba pengaturan solusi
GC.KeepAlive(myTimer)
atau
for (; ; ) { }
}
tetapi mereka tidak bekerja dalam kasus saya.
Berikut dokumentasi Microsoft, ini bekerja dengan sempurna:
using System;
using System.Timers;
public class Example
{
private static Timer aTimer;
public static void Main()
{
// Create a timer and set a two second interval.
aTimer = new System.Timers.Timer();
aTimer.Interval = 2000;
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
// Have the timer fire repeated events (true is the default)
aTimer.AutoReset = true;
// Start the timer
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program at any time... ");
Console.ReadLine();
}
private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
// The example displays output like the following:
// Press the Enter key to exit the program at any time...
// The Elapsed event was raised at 5/20/2015 8:48:58 PM
// The Elapsed event was raised at 5/20/2015 8:49:00 PM
// The Elapsed event was raised at 5/20/2015 8:49:02 PM
// The Elapsed event was raised at 5/20/2015 8:49:04 PM
// The Elapsed event was raised at 5/20/2015 8:49:06 PM