2009-05-25 29 views
5

Đây là vấn đề tôi có: Tôi cần đảm bảo một đối tượng được khởi tạo trên chuỗi giao diện người dùng. Nếu không, nó sẽ ném một ngoại lệ. Nhưng làm thế nào để kiểm tra bên trong một phương thức cho dù nó đang chạy trên thread UI? Lưu ý: Tôi không muốn chuyển bất kỳ thông tin nào vào hàm tạo của đối tượng.Làm cách nào tôi có thể tìm hiểu xem phương thức thực hiện trên chuỗi giao diện người dùng hay không theo cách được tách riêng?

Ứng cử viên hoàn hảo sẽ là DispatcherSynchronizationContext (thực hiện WPF của SynchronizationContext) mà nội bộ chứa tham chiếu đến Dispatcher tham chiếu đến chuỗi liên kết, nhưng tiếc là trường đó là riêng tư nên không có cách nào để tôi truy cập nó.

Trả lời

8

Làm rõ nhỏ, mặc dù thường chỉ có một chuỗi giao diện người dùng có thể có nhiều chuỗi giao diện người dùng. Điều này đúng cho cả WPF và WinForms.

Cách tốt nhất tôi đã tìm thấy để đạt được điều này mặc dù là với một SynchronizationContext. Cả WPF và WinForms sẽ thiết lập một SynchronizationContext trên bất kỳ chủ đề nào mà họ đang chạy giao diện người dùng. Đây là hàm tôi sử dụng nếu tôi không gắn với bất kỳ mô hình giao diện người dùng cụ thể nào.

public bool IsPossiblyUIThread() { 
    return SynchronizationContext.Current != null; 
} 

Lưu ý, nó không phải là cách dễ dàng. Có thể cho các thành phần không phải UI để thiết lập một SynchronizationContext và điều này sẽ trả về true cho một chuỗi công nhân đơn giản. Do đó tên không có thẩm quyền.

A hơi cách đáng tin cậy hơn để thực hiện việc này là như sau. Nhưng nó đòi hỏi bạn phải tham khảo ít nhất một phần của WPF để thực hiện.

public bool IsLikelyWpfUIThread() { 
    var context = SynchronizationContext.Current; 
    return context != null && context is DispatcherSynchronizationContext; 
} 
+0

Vâng, đây có vẻ là cách tốt nhất. Cám ơn rất nhiều! –

2

Dispatcher.CheckAccess() trả về true nếu mã của bạn chạy trên cùng một Thread với Dispatcher. Nó sẽ hoạt động nếu chỉ có một Dispatcher/UIThread.

+1

Điều này có thể đúng, nhưng lưu ý rằng Dispatcher luôn được liên kết với chuỗi nó đã được tạo. Vì vậy, bằng cách sử dụng Dispatcher.CheckAccess() không giúp bạn nhiều nếu đối tượng đã được tạo ra trên một chủ đề khác. –

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