DispatcherTimer bị trễ! Liệu có giải pháp nào khác?

Em có mẫu code như thế này:

public partial class Window2 : Window
    {
        public int i, j;
        public Window2()
        {
            InitializeComponent();
            i = j = 0;
            DispatcherTimer timer1 = new DispatcherTimer();
            timer1.Interval = TimeSpan.FromSeconds(1);
            timer1.Tick += Mega1;
            DispatcherTimer timer2 = new DispatcherTimer();
            timer2.Interval = TimeSpan.FromMilliseconds(10);
            timer2.Tick += Mega2;
            timer1.Start();
            timer2.Start();
        }
        private void Mega1(object sender, EventArgs e)
        {
            mega1.Text = ((i++)*100).ToString();
        }
        private void Mega2(object sender, EventArgs e)
        {
            mega2.Text = (j++).ToString();
        }
    }

mega2, mega1 đều là 2 textblock, Và kết quả là như thế này:

Rõ ràng là cái timer2 trễ hơn timer1 rất nhiều. Em đã search gg về cái tình trạng này, nhưng mấy cái giải pháp của họ ko làm em thấy hài lòng. :))
Mấy bác có giải pháp nào để không bị trễ như thế này ko ạ? Liệu C# có hỗ trợ cái Interval time nào mak nó ko phải cứ sau 1 khoảng thôi gian cho trước mới lặp mà tức là nó lặp theo thời điểm ý (vd: giây thứ nhất code chạy, giây thứ 2 code chạy thay vì sau 1 giây code chạy, sau 1 giây code chạy)?

Timer thì không bao giờ có chính xác. Nên đừng bao giờ hi vọng nó chính xác.
Chính microsoft đã nói như vậy ( lâu rồi quên link). Interval càng nhỏ sai số càng lớn.

em ko đc hiểu ý bác cho lắm???

Một con timer bình thường không phải sau Interval ms nó xảy ra event. Nó sẽ có sai số có thể tới một vài ms tuỳ trạng thái. Đặt interval nhỏ thì sai số vài ms đã tạo ra sai số quá lớn.

1 Like

thế làm 1 con countdown độ chính xác 1/100 giây ko khả thi akkk???
:worried:

Chỉ là tương đối thôi.

1 Like

Nếu muốn code chạy theo các thời điểm thì đành dùng while và if để kiểm tra liên tục vậy.

1 Like

Giải pháp khả thi hơn thì dùng multithread. Tức là tạo một luồng xử lý riêng. Trong đó dùng vòng lặp và thread.sleep. Hoặc vẫn multithread và một vòng lăp liên tục kiểm tra thời gian của một Stopwatch.

Tương tác UI thì dùng beginInvoke (không dùng Invoke).

Về mặt hệ điều hành thì nếu CPU của bạn có càng nhiều core và càng chạy ít chương trình thì khả năng có sai số và độ lớn sai số khi bạn đặt thời gian nhỏ (dưới 100ms) cho timer sẽ càng nhỏ. Điều này đúng cho mọi loại HĐH và mọi loại ứng dụng.

Tham khảo: Context Switch

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?