2016-03-15 15 views
8

Tôi thấy nhiều phương thức trong khung công tác mới sử dụng hỗ trợ mẫu/ngôn ngữ không đồng bộ mới cho async/await trong C#. Tại sao không có cơ chế Monitor.EnterAsync() hoặc cơ chế async lock phát hành chuỗi hiện tại & trả về ngay sau lock khả dụng?Tại sao không có phương thức Monitor.EnterAsync giống như

Tôi cho rằng điều này là không thể - câu hỏi là lý do tại sao?

+0

Tôi biết câu hỏi này về màn hình, nhưng có một số nguyên tắc đồng bộ hóa cung cấp hoạt động không đồng bộ: https://msdn.microsoft.com/en-us/library/hh462723.aspx –

+0

Hoàn toàn có thể! Thật khó để viết (và khó sử dụng hơn), và nó không được trang bị thêm vào lớp 'Monitor' hiện tại vì' Monitor' là một kiểu khá cơ bản để bắt đầu, và đây là một trường hợp khá phức tạp (giả sử bạn thực sự, thực sự cần nó). Xem https://github.com/StephenCleary/AsyncEx/wiki/AsyncMonitor để thực hiện. –

+2

Có thể thực hiện nhưng mọi thứ xảy ra sai khi bạn thử và thực sự sử dụng nó. http://stackoverflow.com/questions/7612602/why-cant-i-use-the-await-operator-within-the-body-of-a-lock-statement – vcsjones

Trả lời

4

Một số nguyên tắc đồng bộ hóa. Nguồn cung cấp Net là trình bao bọc được quản lý xung quanh các đối tượng gốc bên dưới.

Hiện tại, không có nguyên gốc đồng bộ hóa gốc nào triển khai khóa không đồng bộ. Vì vậy, những người thực hiện .Net phải thực hiện điều đó từ đầu, điều này không đơn giản như vậy.

Ngoài ra, nhân Windows không cung cấp bất kỳ tính năng nào của "khóa ủy nhiệm", nghĩa là bạn không thể khóa khóa trong một chuỗi và chuyển quyền sở hữu cho một chuỗi khác. khó khăn. Theo quan điểm của tôi, lý do thứ ba là triết lý thứ ba hơn - nếu bạn không muốn chặn - sử dụng các kỹ thuật không chặn, như sử dụng IO không đồng bộ, khóa các thuật toán và cấu trúc dữ liệu miễn phí. Nếu nút cổ chai của ứng dụng của bạn là ganh đua nặng nề và chi phí khóa xung quanh nó, bạn có thể thiết kế lại ứng dụng của bạn ở dạng khác mà không cần phải có khóa không đồng bộ.

+0

* Màn hình là trình bao bọc xung quanh CRITICAL_SECTION * không đúng. Bạn có thể thêm bất kỳ tài nguyên có thẩm quyền hỗ trợ nào không? –

+0

Lập trình đồng thời trên sổ sách của Joe duffy gọi điều này ra ** Về mặt vật lý, màn hình không bao gồm Windows CRITICAL_SECTION, nhưng nó hoạt động giống như nó. ** Pgno: 272 –

+0

hãy để tôi chỉnh sửa lại câu trả lời –

3

Tôi đoán vấn đề là bằng cách gọi Monitor.Enter chủ đề hiện tại muốn lấy khóa cho đối tượng được truyền. Vì vậy, bạn nên tự hỏi làm thế nào bạn sẽ thực hiện một Monitor.EnterAsync? Đầu tiên nỗ lực ngây thơ sẽ là:

public async Task EnterAsync(object o) 
{ 
    await Task.Run(() => Monitor.Enter(o)); 
} 

Nhưng điều đó rõ ràng là không làm những gì bạn mong đợi, bởi vì các khóa sẽ đạt được bằng sợi chỉ bắt đầu cho rằng mới Task và không phải bởi tiểu trình đang gọi.
Bây giờ bạn sẽ cần một cơ chế để đảm bảo rằng bạn có thể lấy khóa sau khi chờ đợi. Nhưng hiện tại tôi không thể nghĩ ra cách để đảm bảo rằng điều này sẽ hoạt động và không có chủ đề nào khác sẽ lấy được khóa ở giữa.


Đây chỉ là 2 xu của tôi (đã đăng là bình luận nếu không quá dài). Tôi đang mong chờ một câu trả lời sáng suốt hơn cho bạn từ một người có kiến ​​thức chi tiết hơn.

2

Mặc dù không có màn hình không đồng bộ trong .NET theo mặc định, Stephen Cleary có thư viện tuyệt vời AsyncEx đề cập đến vấn đề đồng bộ hóa khi sử dụng async/await.

Nó có lớp học AsyncMonitor, điều này thực hiện chính xác những gì bạn đang tìm kiếm. Bạn có thể lấy từ GitHub hoặc dưới dạng NuGet package.

Cách sử dụng Ví dụ:

var monitor = new AsyncMonitor(); 
using (await monitor.EnterAsync()) 
{ 
    // Critical section 
} 
2

Tôi cho rằng điều này là không thể - câu hỏi là tại sao?

Có thể, nó vẫn chưa được thực hiện.

Hiện tại, nguyên thủy đồng bộ hóa tương thích không đồng bộ hóa duy nhất trong BCL là SemaphoreSlim, có thể hoạt động như một semaphore hoặc khóa loại trừ lẫn nhau đơn giản.

Tôi có số cơ bản AsyncMonitor that I wrote, dựa theo số Stephen Toub's blog post series. Lưu ý rằng ngữ nghĩa hơi khác so với BCL Monitor; đặc biệt, nó không cho phép khóa đệ quy (cho reasons I describe on my blog).

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