จะรีเซ็ตตัวจับเวลาใน C # ได้อย่างไร?


114

มีสามTimerชั้นเรียนที่ฉันรู้, System.Threading.Timer, System.Timers.TimerและSystem.Windows.Forms.Timerแต่ไม่มีของเหล่านี้มี.Reset()ฟังก์ชั่นซึ่งจะรีเซ็ตเวลาที่ผ่านไปในปัจจุบันให้เป็น 0

มีคลาส BCL ที่มีฟังก์ชันนี้หรือไม่? มีวิธีที่ไม่แฮ็กหรือไม่? (ฉันคิดว่าการเปลี่ยนการ จำกัด เวลาอาจรีเซ็ตได้) ลองคิดดูว่าการจะนำTimerคลาสที่มีฟังก์ชันนี้กลับมาใช้ใหม่นั้นยากแค่ไหนหรือจะทำอย่างไรให้น่าเชื่อถือกับหนึ่งในคลาส BCL


3
การใช้โซลูชันของ JP ใช้วิธีการขยาย
benPearce

ฉันก็มีความต้องการในการรีเซ็ตเหมือนกันและด้วยเหตุผลเดียวกันที่กล่าวมา FileSystemWatcher ไม่เป็นที่พอใจและไม่สะดวกที่จะใช้
John Lewin

หากคุณใช้ Stopwatch สำหรับตัวจับเวลาและใช้คำตอบวิธีการขยายโปรดระวังเพราะ Stopwatch.Restart ขยายวิธีมาใน. NET 4.0 msdn.microsoft.com/en-us/library/…
si618

คำตอบ:


150

ฉันทำอยู่เสมอ ...

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

... นั่นคือแฮ็ค? :)

ตามความคิดเห็นใน Threading Timer มันคือวิธีการเปลี่ยน ...

DueTime Type: System.Int32ระยะเวลาในการหน่วงเวลาก่อนที่จะเรียกใช้เมธอดการเรียกกลับที่ระบุเมื่อสร้างตัวจับเวลาเป็นมิลลิวินาที ระบุ Timeout.Infiniteเพื่อป้องกันไม่ให้ตัวจับเวลารีสตาร์ท ระบุศูนย์ (0) เพื่อรีสตาร์ทตัวจับเวลาทันที


ปัญหาอื่น ๆ คือมีเพียงแค่ Forms.Timer เท่านั้นและแอปของฉันไม่มี GUI (Application.Start () ที่ไม่มีพารามิเตอร์) ดังนั้นฉันคิดว่าคลาส Threading.Timer นั้นดีกว่าด้วยเหตุผลอื่น ๆ แต่เป็นจุดที่ดี
Matthew Scharley

3
@ แมทธิว : ดูmsdn.microsoft.com/en-us/magazine/cc164015.aspxสำหรับการอภิปรายเกี่ยวกับคลาสจับเวลาต่างๆและเมื่อใช้งานได้ตามความเหมาะสม โดยทั่วไปแล้วForms.Timerควรใช้กับ GUI เท่านั้น อย่างไรก็ตามนอกเหนือจากForms.Timerและนอกจากนี้ยังมีThreading.Timer Timers.Timer
Brian

60

ตัวจับเวลาทั้งหมดมีวิธีการเทียบเท่ากับ Start () และ Stop () ยกเว้น System.Threading.Timer

ดังนั้นวิธีการขยายเช่น ...

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

... เป็นวิธีหนึ่งที่จะดำเนินการต่อไป


1
ฉันไม่ต้องการวัดเวลาที่ผ่านไป กรณีการใช้งานที่แน่นอนของฉันสำหรับสิ่งนี้คือฉันมี FileSystemWatcher ที่เฝ้าดูไดเร็กทอรีและต้องการจับกลุ่มการเปลี่ยนแปลง (เช่นการเปลี่ยนแปลงที่เกิดขึ้นภายในตัวอย่าง 5 วินาทีของกันและกัน) ทฤษฎีที่ว่าการเปลี่ยนแปลงครั้งแรกจะเริ่มตัวจับเวลาที่ได้รับการรีเซ็ตตามการเปลี่ยนแปลงแต่ละครั้งจนกระทั่งในที่สุดก็เริ่มทำงานและปิดกลุ่ม
Matthew Scharley

ใช่ฉันเห็นว่าเมื่อฉันอ่านคำถามของคุณอีกครั้ง แก้ไขคำตอบของฉัน
Dan

timer.Start()งานนี้และมันเป็นสิ่งสำคัญที่จะต้องทราบว่านี้จะไม่ทำงานถ้าคุณโทรเท่านั้น ฉันทำแบบสอบถาม Linqpad นี้เพื่อทดสอบ ลองลบออกtimer.Stopแล้วคุณจะเห็นความแตกต่าง
Jared Beach

30

สำหรับSystem.Timers.Timerตามเอกสาร MSDN http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx :

หากกำหนดช่วงเวลาไว้หลังจากเริ่มจับเวลาแล้วการนับจะถูกรีเซ็ต ตัวอย่างเช่นหากคุณตั้งค่าช่วงเวลาเป็น 5 วินาทีแล้วตั้งค่าคุณสมบัติเปิดใช้งานเป็นจริงจำนวนจะเริ่มต้นเมื่อตั้งค่าเปิดใช้งาน หากคุณรีเซ็ตช่วงเวลาเป็น 10 วินาทีเมื่อนับเป็น 3 วินาทีเหตุการณ์ที่ผ่านไปจะเพิ่มขึ้นเป็นครั้งแรก 13 วินาทีหลังจากที่เปิดใช้งานถูกตั้งค่าเป็นจริง

ดังนั้น,

    const double TIMEOUT = 5000; // milliseconds

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

    :
    :

    aTimer.Interval = TIMEOUT;  // restart the timer

1
ปัญหาคือคุณมักจะไม่รู้ในขณะที่คุณต้องการรีเซ็ตว่าตัวจับเวลาทำงานอยู่แล้วหรือไม่ ดังนั้นคุณจะต้องทำ aTimer.Interval = TIMEOUT และ aTimer.Start () ดังนั้นโดยรวมแล้วฟังก์ชันรีเซ็ตด้านบนจึงใช้บรรทัดและตัวแปรน้อยลง นอกจากนี้ที่ดีแม้ว่า
e-Mot

1
@ RU-Bn OP ระบุอย่างชัดเจน " a .Reset () ฟังก์ชั่นซึ่งจะรีเซ็ตเวลาที่ผ่านไปในปัจจุบันเป็น 0 " - ไม่ได้ระบุว่ามีจุดประสงค์เพื่อใช้กับแอปพลิเคชันที่ออกแบบมาไม่ดีโดยที่คุณไม่รู้ด้วยซ้ำว่าตัวจับเวลากำลังทำงานอยู่หรือไม่ ตรวจสอบความคิดเห็นของผู้เขียนด้วย (มากกว่า 4 ปีที่แล้ว): " ทฤษฎีที่ว่าการเปลี่ยนแปลงครั้งแรกจะเริ่มจับเวลาซึ่งจะรีเซ็ตตามการเปลี่ยนแปลงแต่ละครั้งจนในที่สุดก็เริ่มทำงานและปิดกลุ่ม " ขอบคุณสำหรับการโหวตลงอย่างไรก็ตาม
mMontu

ฉันก็เห็นปัญหาเช่นนั้น สิ่งที่ฉันทำคือ: aTimer.Interval = aTimer.Interval นั่นทำให้เกิดการวนซ้ำ เต้นฉันทำไม แต่มันได้ผล ...
Herman Van Der Blom

7

คุณสามารถเขียนวิธีการขยายที่เรียกว่ารีเซ็ต () ซึ่ง

  • เรียก Stop () - Start () สำหรับ Timers Timer และ Forms.Timer
  • เรียกเปลี่ยนสำหรับ Threading Timer

5

ฉันเพิ่งกำหนดค่าใหม่ให้กับตัวจับเวลา:

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

มันใช้งานได้ดีสำหรับฉัน

ที่ด้านบนของรหัสกำหนดตัวจับเวลา: 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

เพื่อความชัดเจนเนื่องจากความคิดเห็นอื่น ๆ ไม่ถูกต้องเมื่อใช้System.Timersการตั้งค่าเปิดใช้งานเป็นจริงจะรีเซ็ตเวลาที่ผ่านไป ฉันเพิ่งทดสอบพฤติกรรมดังต่อไปนี้:

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

ฉันจะป้อนข้อความในกล่องข้อความซ้ำ ๆ และตัวจับเวลาจะทำงานเพียง 3 วินาทีหลังจากการกดแป้นพิมพ์ครั้งสุดท้าย มีคำใบ้อยู่ในเอกสารเช่นกันดังที่คุณจะเห็น: การโทรTimers.Start()เพียงแค่ตั้งค่าเปิดใช้งานเป็นจริง

และเพื่อให้แน่ใจว่าที่ฉันควรจะได้เพียงแค่เดินตรงไปจากจุดเริ่มต้นคุณจะเห็นในแหล่งอ้างอิง .NETว่าถ้าเปิดใช้งานการตั้งเวลาเปิดใช้งานแล้วมันเรียกเอกชนวิธีการซึ่งภายในสายUpdateTimer()Change()


ไม่คุณผิด ส่วนตัวUpdateTtimerวิธีการที่เรียกว่าถ้าหากค่าปัจจุบันของไม่เท่ากับใหม่Enabled value
Nicolò Carandini

3

สำหรับ Timer (System.Windows.Forms.Timer)

วิธีการ. หยุดแล้ว. เริ่มทำงานเป็นการรีเซ็ต


1

วิธีอื่นในการรีเซ็ต windows.timer คือการใช้ตัวนับดังนี้:

int tmrCtr = 0;
Timer mTimer;

private void ResetTimer()
{
  tmrCtr = 0;
}

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

ดังนั้นหากคุณตั้งใจจะทำซ้ำทุก ๆ 1 วินาทีคุณสามารถตั้งช่วงเวลาจับเวลาที่ 100ms และทดสอบตัวนับเป็น 10 รอบ

เหมาะสำหรับผู้จับเวลาควรรอให้กระบวนการบางอย่างซึ่งอาจสิ้นสุดลงในช่วงเวลาที่ต่างกัน


1

ฉันทำนี่

//Restart the timer
queueTimer.Enabled = true;

แค่นี้ก็เปิดใช้งานได้แล้ว แม้ว่าจะปิดใช้งานไว้ก่อนการเปิดใช้งานอีกครั้งจะไม่เปลี่ยนแปลงเวลาที่ผ่านไปที่รวบรวมไว้จนถึงจุดนั้น
vapcguy

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.