2010-02-13 38 views
21

Vui lòng giải thích sự khác biệt giữa "DispatcherTimer" và "Bộ định thời thường xuyên" @Kent Boogaart có nghĩa là để sử dụng trong ứng dụng WPF đa luồng như một công cụ quản lý tác vụ trong chủ đề này:DispatcherTimer vs Bộ hẹn giờ bình thường trong ứng dụng WPF cho công cụ lên lịch

Advice needed for multi-threading strategy for WPF application

trong bài bình luận với một trong những bài (quote):

-Nếu tất cả các DispatcherTimer làm là khởi thread khác, điểm của việc sử dụng các DispatcherTimer là gì? .... những chủ đề đó không cần phải bắt đầu trên chuỗi giao diện người dùng. Bạn chỉ có thể sử dụng Bộ hẹn giờ thông thường và tránh làm gián đoạn giao diện người dùng hoàn toàn

"Bộ hẹn giờ thông thường" có nghĩa là gì? Làm thế nào họ ("DispatcherTimer" và "một Timer thường xuyên") khác nhau về tác động của họ trên UI?

(Cho đến khi đọc bài viết này, tôi nghĩ về DispatcherTimer như là một cách tự nhiên của việc sử dụng tính giờ trong WPF. Các trường hợp là gì khi điều này là không đúng?)

Trả lời

39

DispatcherTimer là hẹn giờ thông thường. Nó kích hoạt sự kiện Tick của nó trên chuỗi giao diện người dùng, bạn có thể làm bất cứ điều gì bạn muốn với giao diện người dùng. System.Timers.Timer là một bộ đếm thời gian không đồng bộ, sự kiện Elapsed của nó chạy trên một luồng thread thread. Bạn phải rất cẩn thận trong trình xử lý sự kiện của mình, bạn không được phép chạm vào bất kỳ thành phần giao diện người dùng hoặc biến dữ liệu nào bị ràng buộc. Và bạn sẽ cần phải sử dụng báo cáo khóa khi bạn truy cập các thành viên lớp học cũng được sử dụng trên chuỗi giao diện người dùng.

Trong câu trả lời được liên kết, lớp Timer thích hợp hơn vì OP cố gắng chạy mã không đồng bộ theo mục đích.

+0

lưu ý rằng 'chạm' bao gồm thiết lập các thuộc viewmodel MVVM vì thế khi sử dụng một DispatcherTimer bạn đang sử dụng tốt, nhưng với một Timer bạn thậm chí không thể làm điều đó –

26

Sự kiện Đánh dấu thời gian bình thường thực sự được kích hoạt trên chuỗi nơi Bộ hẹn giờ được tạo, vì vậy trong sự kiện đánh dấu để truy cập mọi thứ bằng giao diện người dùng, bạn sẽ phải đi qua dispatcher.begininvoke như được đề cập bên dưới.

RegularTimer_Tick(object sender, EventArgs e) 
{ 
    txtBox1.Text = "count" + i.ToString(); 
    // error can not access 
    // txtBox1.Text property outside dispatcher thread... 

    // instead you have to write... 
    Dispatcher.BeginInvoke((Action)delegate(){ 
     txtBox1.Text = "count " + i.ToString(); 
    }); 
} 

Trong trường hợp Dispatcher Timer, bạn có thể truy cập vào các yếu tố giao diện người dùng mà không làm bắt đầu invoke hoặc gọi như sau ...

DispatcherTimer_Tick(object sender, EventArgs e) 
{ 
    txtBox1.Text = "Count " + i.ToString(); 
    // no error here.. 
} 

DispatcherTimer chỉ cung cấp thuận tiện hơn hẹn giờ thường xuyên truy cập vào đối tượng giao diện người dùng một cách dễ dàng.

+1

Cám ơn các ví dụ mã, 1 – rem

+0

là điều phối hẹn giờ sử dụng Invoke hoặc BeginInvoke? –

+0

Dựa trên nguồn ở đây, DispatcherTimer đang sử dụng BeginInvoke, lý do là, hàng đợi điều phối có cơ chế gọi ưu tiên dựa trên. http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/Threading/DispatcherTimer.cs,d2a05f6b09eee858 –

14

Với .NET 4.5 bạn cũng có thể tạo đại biểu async cho bộ hẹn giờ nếu bạn cần sử dụng chức năng .NET 4.5 await mới.

 var timer = new DispatcherTimer(); 
     timer.Interval = TimeSpan.FromSeconds(20); 
     timer.Tick += new EventHandler(async (object s, EventArgs a) => 
     { 
      Message = "Updating..."; 
      await UpdateSystemStatus(false); 
      Message = "Last updated " + DateTime.Now;    
     }); 
     timer.Start(); 
+0

điều này cũng có thể được quan tâm (câu hỏi của riêng tôi tìm kiếm một DispatcherTimer thân thiện không đồng bộ) http://stackoverflow.com/câu hỏi/12442622/async-aware-friendly-dispatchertimer-wrapper-subclass/12442719 # 12442719 –

Các vấn đề liên quan