Làm cách nào để đặt lại bộ hẹn giờ trong C #?


114

Có ba Timerlớp học mà tôi biết, System.Threading.Timer, System.Timers.Timer, và System.Windows.Forms.Timer, nhưng không ai trong số này có một .Reset()chức năng mà sẽ đặt lại thời gian trôi qua hiện tại để 0.

Có lớp BCL nào có chức năng này không? Có cách nào không hack không? (Tôi nghĩ có lẽ việc thay đổi giới hạn thời gian có thể đặt lại nó) Hãy nghĩ xem việc thực hiện lại một Timerlớp có chức năng này sẽ khó như thế nào hoặc làm cách nào để thực hiện nó một cách đáng tin cậy với một trong các lớp BCL?


3
Bằng quyền sử dụng giải pháp JP của một phương pháp khuyến nông
benPearce

Tôi cũng có nhu cầu tương tự cho thiết lập lại và vì những lý do tương tự đã đề cập, FileSystemWatcher là khó chịu và bất tiện để sử dụng
John Lewin

Nếu bạn sử dụng Đồng hồ bấm giờ để hẹn giờ và đi kèm với câu trả lời là phương thức mở rộng, hãy cẩn thận vì phương thức mở rộng Stopwatch.Restart sắp có trong .NET 4.0. msdn.microsoft.com/en-us/library/…
si618

Câu trả lời:


148

Tôi luôn luôn làm ...

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

... đó có phải là hack không? :)

Theo nhận xét, trên Threading.Timer, đó là phương pháp Thay đổi ...

Loại System.Int32thời gian do : Khoảng thời gian để trì hoãn trước khi gọi phương thức gọi lại được chỉ định khi Bộ hẹn giờ được tạo, tính bằng mili giây. Chỉ định Timeout.Infiniteđể ngăn bộ hẹn giờ khởi động lại. Chỉ định số không (0) để khởi động lại bộ hẹn giờ ngay lập tức.


Vấn đề khác là chỉ gặp rắc rối với Forms.Timer và ứng dụng của tôi không có GUI (Application.Start () không có tham số), vì vậy tôi NGHĨ rằng lớp Threading.Timer tốt hơn vì những lý do khác, nhưng điểm tốt.
Matthew Scharley

3
@Matthew: Xem msdn.microsoft.com/en-us/magazine/cc164015.aspx để biết thảo luận về các lớp hẹn giờ khác nhau và khi nào sử dụng chúng là phù hợp. Tuy nhiên, nói chung, Forms.Timerchỉ nên được sử dụng với GUI. Tuy nhiên, bên cạnh đó Forms.TimerThreading.Timercũng có Timers.Timer.
Brian

60

Tất cả các bộ định thời đều có phương thức Start () và Stop () tương đương, ngoại trừ System.Threading.Timer.

Vì vậy, một phương pháp mở rộng như ...

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

... là một cách để đi về nó.


1
Tôi không muốn đo thời gian đã trôi qua. Lợi ích chính xác của tôi cho điều này là tôi có một FileSystemWatcher đang xem một thư mục và muốn nắm bắt các nhóm thay đổi (tức là các thay đổi được thực hiện trong vòng 5 giây của nhau chẳng hạn). Lý thuyết là thay đổi đầu tiên bắt đầu một bộ đếm thời gian được đặt lại với mỗi thay đổi cho đến khi cuối cùng nó kích hoạt và đóng nhóm.
Matthew Scharley

Vâng, tôi đã phát hiện ra điều đó khi tôi đọc lại câu hỏi của bạn. Đã chỉnh sửa câu trả lời của tôi.
Dan

Điều này hoạt động và điều quan trọng cần lưu ý là điều này sẽ không hoạt động nếu bạn chỉ gọi timer.Start(). Tôi đã thực hiện truy vấn Linqpad này để kiểm tra nó. Hãy thử loại bỏ timer.Stoptrong đó và bạn sẽ thấy sự khác biệt.
Bãi biển Jared

30

Đối với System.Timers.Timer, theo tài liệu MSDN, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx :

Nếu khoảng thời gian được đặt sau khi Bộ hẹn giờ bắt đầu, thì bộ đếm sẽ được đặt lại. Ví dụ: nếu bạn đặt khoảng thời gian là 5 giây và sau đó đặt thuộc tính Đã bật thành true, thì số lượng sẽ bắt đầu tại thời điểm Đã bật được đặt. Nếu bạn đặt lại khoảng thời gian thành 10 giây khi số đếm là 3 giây, thì sự kiện Đã qua được nâng lên lần đầu tiên 13 giây sau khi Đã bật được đặt thành đúng.

Vì thế,

    const double TIMEOUT = 5000; // milliseconds

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

    :
    :

    aTimer.Interval = TIMEOUT;  // restart the timer

1
Vấn đề ở đây là bạn không phải lúc nào cũng biết tại thời điểm bạn muốn đặt lại bộ hẹn giờ đã chạy hay chưa. Vì vậy, bạn sẽ phải thực hiện aTimer.Interval = TIMEOUT và aTimer.Start (). Vì vậy, tổng thể, một hàm đặt lại ở trên sử dụng ít dòng và biến hơn. Bổ sung tuyệt vời mặc dù.
e-motiv

1
@ RU-Bn OP nêu rõ " một hàm .Reset () sẽ đặt lại thời gian đã trôi qua hiện tại về 0. " - nó không đề cập rằng nó được dự định để sử dụng trên một ứng dụng được thiết kế kém, nơi bạn thậm chí không biết bộ hẹn giờ có đang chạy hay không. Cũng kiểm tra nhận xét của tác giả (hơn 4 năm trước): " Lý thuyết là thay đổi đầu tiên bắt đầu một bộ đếm thời gian được đặt lại với mỗi thay đổi cho đến khi nó cuối cùng kích hoạt và đóng nhóm. ". Dù sao cũng cảm ơn vì đã bỏ phiếu.
mMontu

Tôi cũng thấy một vấn đề như thế. Những gì tôi đã làm là: aTimer.Interval = aTimer.Interval. Điều đó kích hoạt rằng vòng lặp đang diễn ra. Beats tôi tại sao nhưng nó hoạt động ...
Herman Van Der Blom

7

Bạn có thể viết một phương thức mở rộng có tên là Reset (),

  • gọi Stop () - Start () cho Timers.Timer và Forms.Timer
  • cuộc gọi Thay đổi cho Threading.Timer

5

Tôi vừa gán một giá trị mới cho bộ hẹn giờ:

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

Việc này ổn với tôi.

ở đầu mã xác định bộ đếm thời gian: 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

Để rõ ràng vì một số nhận xét khác không chính xác, khi sử dụng System.Timerscài đặt Đã bật thành đúng sẽ đặt lại thời gian đã trôi qua. Tôi vừa kiểm tra hành vi với những điều sau:

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");
}

Tôi sẽ nhập văn bản vào hộp văn bản nhiều lần và bộ đếm thời gian sẽ chỉ chạy 3 giây sau lần nhấn phím cuối cùng. Nó cũng được gợi ý trong tài liệu, như bạn sẽ thấy: việc gọi Timers.Start()đơn giản chỉ đặt Enabled thành true.

Và để chắc chắn, điều mà tôi nên đi thẳng ngay từ đầu, bạn sẽ thấy trong nguồn tham chiếu .NET rằng nếu bật bộ hẹn giờ đã Bật thì nó sẽ gọi UpdateTimer()phương thức riêng tư , phương thức này sẽ gọi nội bộ Change().


Không, bạn sai rồi. UpdateTtimerPhương thức private được gọi nếu và chỉ khi giá trị hiện tại của Enabledkhông bằng giá trị mới value.
Nicolò Carandini

3

Đối với Bộ hẹn giờ (System.Windows.Forms.Timer).

Các phương thức .Stop, sau đó .Start hoạt động như một thiết lập lại.


1

Cách thay thế khác để đặt lại windows.timer là sử dụng bộ đếm, như sau:

int tmrCtr = 0;
Timer mTimer;

private void ResetTimer()
{
  tmrCtr = 0;
}

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

Vì vậy, nếu bạn định lặp lại sau mỗi 1 giây, bạn có thể đặt khoảng thời gian hẹn giờ ở 100ms và kiểm tra bộ đếm thành 10 chu kỳ.

Điều này phù hợp nếu bộ hẹn giờ nên đợi một số quá trình có thể kết thúc ở khoảng thời gian khác.


1

tôi làm việc này

//Restart the timer
queueTimer.Enabled = true;

Điều này chỉ cho phép nó. Ngay cả khi nó đã bị tắt trước đó, việc bật lại không thay đổi thời gian đã trôi qua đã được thu thập cho đến thời điểm đó.
vapcguy

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.