Bagaimana cara mengatur ulang timer di C #?


114

Ada tiga Timerkelas yang saya sadar, System.Threading.Timer, System.Timers.Timer, dan System.Windows.Forms.Timer, namun tidak satupun dari ini memiliki .Reset()fungsi yang akan mengatur ulang waktu yang telah berlalu saat ini untuk 0.

Apakah ada kelas BCL yang memiliki fungsi ini? Apakah ada cara non-hack untuk melakukannya? (Saya pikir mungkin mengubah batas waktu di atasnya mungkin akan mengatur ulang) Berpikir tentang betapa sulitnya untuk menerapkan kembali Timerkelas yang memiliki fungsi ini, atau bagaimana melakukannya dengan andal dengan salah satu kelas BCL?


3
Menggunakan solusi JP gunakan metode ekstensi
benPearce

Saya juga memiliki kebutuhan yang sama untuk mengatur ulang dan untuk alasan yang sama disebutkan, FileSystemWatcher tidak menyenangkan dan tidak nyaman untuk digunakan
John Lewin

Jika Anda menggunakan Stopwatch untuk pengatur waktu dan menggunakan jawaban metode ekstensi, berhati-hatilah karena metode ekstensi Stopwatch.Restart akan datang dalam .NET 4.0. msdn.microsoft.com/en-us/library/…
si618

Jawaban:


148

Aku selalu melakukan ...

myTimer.Stop();
myTimer.Start();

... apakah itu hack? :)

Per komentar, di Threading.Timer, ini adalah metode Ubah ...

dueTime Type: System.Int32Jumlah waktu penundaan sebelum pemanggilan metode callback yang ditentukan saat Timer dibuat, dalam milidetik. Tentukan Timeout.Infiniteuntuk mencegah timer memulai ulang. Tentukan nol (0) untuk segera memulai ulang pengatur waktu.


Masalah lainnya adalah bahwa hanya beberapa minggu dengan Forms.Timer, dan aplikasi saya tidak memiliki GUI (Application.Start () tanpa parameter), jadi saya BERPIKIR bahwa kelas Threading.Timer lebih baik karena alasan lain, tetapi poin yang bagus.
Matthew Scharley

3
@Matthew: Lihat msdn.microsoft.com/en-us/magazine/cc164015.aspx untuk diskusi tentang berbagai kelas pengatur waktu dan kapan menggunakannya yang sesuai. Namun secara umum, Forms.Timersebaiknya hanya digunakan dengan GUI. Namun, selain Forms.Timerdan Threading.Timerada juga Timers.Timer.
Brian

60

Semua pengatur waktu memiliki metode yang setara dengan Start () dan Stop (), kecuali System.Threading.Timer.

Jadi metode penyuluhan seperti ...

public static void Reset(this Timer timer)
{
  timer.Stop();
  timer.Start();
}

... adalah salah satu cara untuk melakukannya.


1
Saya tidak ingin mengukur waktu yang telah berlalu. Kasus penggunaan tepat saya untuk ini adalah bahwa saya memiliki FileSystemWatcher yang mengawasi direktori dan ingin menangkap sekelompok perubahan (yaitu, perubahan yang dibuat dalam misalnya 5s satu sama lain). Teorinya adalah bahwa perubahan pertama memulai pengatur waktu yang disetel ulang dengan setiap perubahan sampai akhirnya mengaktifkan dan menutup grup.
Matthew Scharley

Ya, saya melihatnya saat membaca ulang pertanyaan Anda. Mengedit jawaban saya.
Dan

Ini berfungsi dan penting untuk dicatat bahwa ini tidak akan berfungsi jika Anda hanya menelepon timer.Start(). Saya membuat query Linqpad ini untuk mengujinya. Coba hapus timer.Stopdi dalamnya dan Anda akan melihat perbedaannya.
Pantai Jared

30

Untuk System.Timers.Timer, menurut dokumentasi MSDN, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx :

Jika jeda disetel setelah Timer dimulai, hitungan disetel ulang. Misalnya, jika Anda menyetel interval ke 5 detik dan kemudian menyetel properti Diaktifkan ke true, penghitungan dimulai saat Diaktifkan disetel. Jika Anda mengatur ulang interval ke 10 detik saat hitungan 3 detik, Peristiwa berlalu dimunculkan untuk pertama kalinya 13 detik setelah Diaktifkan ditetapkan ke benar.

Begitu,

    const double TIMEOUT = 5000; // milliseconds

    aTimer = new System.Timers.Timer(TIMEOUT);
    aTimer.Start();     // timer start running

    :
    :

    aTimer.Interval = TIMEOUT;  // restart the timer

1
Masalah di sini adalah Anda tidak selalu tahu pada saat Anda ingin mengatur ulang apakah pengatur waktu sudah berjalan atau tidak. Jadi, Anda harus melakukan aTimer.Interval = TIMEOUT dan aTimer.Start (). Jadi secara keseluruhan, fungsi reset di atas menggunakan lebih sedikit baris dan variabel. Tambahan yang bagus.
e-motiv

1
@ RU-Bn OP dengan jelas menyatakan " a .Reset () fungsi yang akan mengatur ulang waktu yang telah berlalu saat ini ke 0. " - tidak disebutkan bahwa ini dimaksudkan untuk digunakan pada aplikasi yang dirancang dengan buruk di mana Anda bahkan tidak tahu apakah pengatur waktunya sedang berjalan. Juga periksa komentar penulis (lebih dari 4 tahun yang lalu): " Teorinya adalah bahwa perubahan pertama memulai pengatur waktu yang disetel ulang dengan setiap perubahan hingga akhirnya diaktifkan dan ditutup dari grup. ". Terima kasih atas suara negatifnya.
mMontu

Saya juga melihat masalah seperti itu. Apa yang saya lakukan adalah: aTimer.Interval = aTimer.Interval. Itu memicu bahwa loop sedang berlangsung. Mengalahkan saya mengapa tapi berhasil ...
Herman Van Der Blom

7

Anda bisa menulis metode ekstensi yang disebut Reset (), yang

  • panggilan Berhenti () - Mulai () untuk Timers.Timer dan Forms.Timer
  • panggilan Ubah untuk Threading.Timer

5

Saya baru saja menetapkan nilai baru ke timer:

mytimer.Change(10000, 0); // reset to 10 seconds

itu bekerja dengan baik untuk saya.

di bagian atas kode tentukan pengatur waktu: System.Threading.Timer myTimer;

if (!active)
        {
            myTimer= new System.Threading.Timer(new TimerCallback(TimerProc));
        }
        myTimer.Change(10000, 0);
        active = true;

private void TimerProc(object state)
    {
        // The state object is the Timer object.
        System.Threading.Timer t = (System.Threading.Timer)state;
        t.Dispose();
        Console.WriteLine("The timer callback executes.");
        active = false;
        //action to do when timer is back to zero
    }

5

Untuk kejelasan karena beberapa komentar lain tidak benar, saat menggunakan System.Timerspengaturan Diaktifkan ke true akan mengatur ulang waktu yang telah berlalu. Saya baru saja menguji perilakunya dengan di bawah ini:

Timer countDown= new Timer(3000);

Main()
{
    TextBox.TextDidChange += TextBox_TextDidChange;
    countdown.Elapsed += CountDown_Elapsed;
}

void TextBox_TextDidChange(Object sender, EventArgs e)
{
    countdown.Enabled = true;
}

void CountDown_Elapsed(object sender, EventArgs e)
{
    System.Console.WriteLine("Elapsed");
}

Saya akan memasukkan teks ke kotak teks berulang kali dan pengatur waktu hanya akan berjalan 3 detik setelah penekanan tombol terakhir. Ini diisyaratkan di dokumen juga, seperti yang akan Anda lihat: pemanggilan Timers.Start()cukup set Diaktifkan ke true.

Dan untuk memastikan, yang seharusnya saya langsung ke dari awal, Anda akan melihat di sumber referensi .NET bahwa jika mengaktifkan pengatur waktu yang sudah Diaktifkan itu memanggil UpdateTimer()metode pribadi , yang secara internal memanggil Change().


Tidak, kamu salah. UpdateTtimerMetode privat dipanggil jika dan hanya jika nilai saat Enabledini tidak sama dengan yang baru value.
Nicolò Carandini

3

Untuk Timer (System.Windows.Forms.Timer).

Metode .Stop, lalu .Start berfungsi sebagai reset.


1

Cara alternatif lain untuk mereset windows.timer adalah menggunakan counter, sebagai berikut:

int tmrCtr = 0;
Timer mTimer;

private void ResetTimer()
{
  tmrCtr = 0;
}

private void mTimer_Tick()
{
  tmrCtr++;
  //perform task
}  

Jadi, jika Anda bermaksud untuk mengulang setiap 1 detik, Anda dapat mengatur interval pengatur waktu pada 100ms, dan menguji penghitung hingga 10 siklus.

Ini cocok jika pengatur waktu harus menunggu beberapa proses yang mungkin berakhir pada rentang waktu yang berbeda.


1

saya melakukan ini

//Restart the timer
queueTimer.Enabled = true;

Ini hanya memungkinkannya. Meskipun dinonaktifkan sebelumnya, pengaktifan ulang tidak mengubah waktu yang telah berlalu yang telah dikumpulkan hingga saat itu.
vapcguy

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.