2012-10-02 26 views
31

Tôi có một ứng dụng mà tôi có một tài nguyên được chia sẻ (một hệ thống Chuyển động) có thể được nhiều khách hàng truy cập. Tôi có các Hoạt động riêng lẻ yêu cầu quyền truy cập vào hệ thống trong suốt thời gian di chuyển và điều này sẽ ném ngoại lệ 'Bận' nếu các hoạt động xung đột được yêu cầu cùng một lúc. Tôi cũng có Sequencers cần có quyền truy cập độc quyền vào hệ thống Chuyển động để thực hiện một số Hoạt động, xen kẽ với các hành động khác; trong toàn bộ chuỗi, không có ứng dụng khách nào khác có thể chạy Hoạt động.Khóa tài nguyên với async/await

Tôi đã tiếp cận truyền thống này bằng cách sử dụng Mối quan hệ chủ đề, để Chủ đề có thể yêu cầu quyền truy cập độc quyền và chạy các cuộc gọi chặn tương ứng với hoạt động. Mặc dù Chủ đề có quyền truy cập nhưng không có Chủ đề nào khác có thể sử dụng tài nguyên. Vấn đề tôi đang gặp bây giờ là tôi đã chuyển sang việc triển khai hệ thống của mình bằng cách sử dụng các mẫu async/await, để cho phép thực thi trình tự bộ lọc sạch hơn. Vấn đề là bây giờ trình sắp xếp của tôi không phải lúc nào cũng chạy trên cùng một luồng; chuỗi hoạt động có thể thay đổi trong suốt quá trình gọi lại, do đó, không còn dễ dàng xác định xem tôi đang ở trong ngữ cảnh hợp lệ để tiếp tục chạy các hoạt động hay không. Một trong những lưu ý là một số các hoạt động tự bao gồm chờ đợi, có nghĩa là cả hai trình tự và hoạt động cá nhân có thể span nhiều chủ đề.

Câu hỏi của tôi: không ai biết về một mô hình tốt để đối phó với việc giành quyền truy cập độc quyền trong sự hiện diện của chuyển đổi luồng do không đồng bộ/chờ đợi?

Để tham khảo, một vài điều tôi đã xem xét:

  1. tôi có thể tạo ra một SynchronizationContext tùy chỉnh mà marshals tất cả sequencer gọi trong suốt thời gian của một chuỗi trở về một chủ đề duy nhất. Điều này có lợi cho phép tôi sử dụng lại mã quản lý quyền truy cập luồng hiện tại của mình. Nhược điểm là điều này sẽ yêu cầu cống hiến một Chủ đề bất cứ khi nào tôi làm hoặc là một chuỗi hoặc một hoạt động (kể từ khi hoạt động cũng có thể span nhiều chủ đề.)

  2. Tạo một mã thông báo truy cập để truy cập vào các phương pháp hoạt động để chứng minh rằng bạn có truy cập có được. Điều này có nhược điểm của các phương thức bloating với một tham số token.

  3. Sử dụng phương pháp tiếp cận mã thông báo truy cập từ (2), nhưng tạo triển khai giao diện trùng lặp cho giao diện Hoạt động để trình bao bọc có thể được khởi tạo với mã thông báo 'nướng-in'. Điều này tạo ra một số mã keo xấu xí, nhưng nó làm sạch mã trình tự để nó không còn cần phải chuyển một mã thông báo cho mỗi phương thức.

Trả lời

22

Câu hỏi của tôi: không ai biết của một mô hình tốt để đối phó với việc mua độc quyền trong sự hiện diện của chuyển đổi chủ đề do async/chờ đợi?

Có, bạn có thể sử dụng AsyncLock, cũng có sẵn như một phần của AsyncEx library của tôi. Nếu bạn muốn có một "TryLock" loại hoạt động, sau đó bạn có thể phải tạo nguyên thủy của riêng bạn.

Bạn mất một số khả năng để thực hiện kiểm tra an toàn: không có cách nào để kiểm tra xem chuỗi hiện đang thực hiện có cụ thể là AsyncLock hay không.

Các tùy chọn khác bao gồm ConcurrentExclusiveSchedulerPair (mà tôi viết blog về here) hoặc TPL Dataflow.

+0

Tôi sẽ đánh dấu đây là câu trả lời cho việc đọc hữu ích. Cuối cùng tôi đã tạo ra proxy cho các giao diện bao gồm kiểm tra truy cập. Sau đó tôi có thể đưa ra một proxy 'truy cập độc quyền' dùng một lần đặc biệt để ngăn các trường hợp proxy khác sử dụng hệ thống trong khi nó còn sống. –

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