Chúng tôi có thư viện đang được WPF và/hoặc máy khách Winform sử dụng.Đồng bộ hóa trên Async tránh bế tắc và ngăn giao diện người dùng bị phản ứng
Chúng tôi đã cung cấp một phương pháp không đồng bộ tương tự như:
Task<int> GetIntAsync()
Chúng tôi cũng đã (không may) cung cấp một phương pháp wrapper đồng bộ:
int GetInt();
mà thực chất chỉ là gọi phương thức không đồng bộ và cuộc gọi .Result
về nhiệm vụ của nó. Gần đây, chúng tôi đã nhận ra trong một số trường hợp, một số mã trong số GetIntAsync
cần chạy trên luồng giao diện người dùng chính (cần sử dụng thành phần COM cũ được đánh dấu là mô hình Luồng "Đơn" (tức là thành phần phải chạy trong phần chính). STA chủ đề không chỉ là chủ đề bất kì STA)
vì vậy, vấn đề là khi GetInt()
được gọi vào các chủ đề chính, nó sẽ bế tắc từ
- các
.Result
khối các chủ đề chính, - mã trong số
GetIntAsync()
sử dụngDispatcher.Invoke
để cố gắng chạy trên chuỗi chính.
Phương pháp đồng bộ đã được tiêu thụ nên sẽ là một thay đổi đột phá để xóa nó. Vì vậy, thay vào đó, chúng tôi đã chọn sử dụng WaitWithPumping trong phương thức GetInt()
đồng bộ của chúng tôi để cho phép lời gọi đến chuỗi chính hoạt động.
Tính năng này hoạt động tốt ngoại trừ khách hàng sử dụng GetInt()
từ mã giao diện người dùng của họ. Trước đây, họ hy vọng rằng việc sử dụng GetInt()
sẽ khiến giao diện người dùng của họ không phản hồi - tức là, nếu họ gọi là GetInt()
từ bên trong trình xử lý sự kiện nhấp chuột của nút, họ sẽ không có thông báo nào được xử lý cho đến khi trình xử lý trả về. Bây giờ các tin nhắn được bơm, giao diện người dùng của chúng tôi là đáp ứng và nút tương tự đó có thể được nhấp lại (và có thể họ không mã hóa trình xử lý của họ để được tham gia lại).
Nếu có một giải pháp hợp lý, chúng tôi muốn không có khách hàng của chúng tôi cần phải mã hóa chống lại giao diện người dùng được đáp ứng trong một cuộc gọi đến GetInt
Câu hỏi:
- Có cách để thực hiện
WaitWithPumping
sẽ bơm thông báo "Gọi đến chính", nhưng không bơm các tin nhắn liên quan đến giao diện người dùng khác? - Sẽ đủ cho mục đích của chúng tôi nếu giao diện người dùng của khách hàng hoạt động như thể một hộp thoại phương thức hiện được hiển thị, mặc dù bị ẩn (tức là người dùng không thể truy cập các cửa sổ khác). Nhưng, từ những gì tôi đọc, bạn không thể ẩn một hộp thoại phương thức.
- Các cách giải quyết khác mà bạn có thể nghĩ đến sẽ được đánh giá cao.
Cảm ơn. Tôi thấy khối giao diện người dùng. Không may mã cố gắng để có được các chủ đề chính là sử dụng Dispatcher chủ đề chính 'Dispatcher.Invoke' để có được chủ đề chính. Tôi đoán để thực hiện công việc này tôi sẽ cần phải thay đổi mã đó để sử dụng SynchronizationContext, chứ không phải là Dispatcher của chủ đề chính. Có cách nào để làm cho nó hoạt động với Dispatcher của thread chính không? –
@MattSmith Mã của bạn không hoạt động cụ thể vì bạn đang sử dụng bộ điều phối của chủ đề chính. – Servy