2015-05-25 14 views
11

Tôi đã cố gắng triển khai Stream hỗ trợ ReadAsyncWriteAsync và được cung cấp mức độ không đáng kể của documentation, tôi đang cố gắng tìm hiểu cách thực hiện đúng cách. Cụ thể, đối với vị trí con trỏ của luồng. Một câu hỏi tương tự đã được hỏi herehere liên quan đến chức năng cũ BeginRead. Tài liệu cho hàm đó dường như chỉ ra rằng không nên gọi lại BeginRead cho đến khi bất kỳ hoạt động không đồng bộ đang chờ xử lý nào đã hoàn thành.Stream.ReadAsync và Stream.WriteAsync có phải thay đổi vị trí con trỏ đồng bộ trước khi trở về hoặc sau khi thao tác hoàn tất không?

Cho rằng BeginRead tại là phảnno longer recommended for new developmentStream đã có khả năng được thay đổi đáng kể để thực hiện các chức năng Async mới, mọi thứ đang một lần nữa rõ ràng. (EDIT: Thông thường loại cảnh báo này có nghĩa là các chức năng mới được thực hiện trực tiếp và các chức năng cũ gọi các chức năng mới và chỉ còn ở đó để tương thích ngược, nhưng dường như không hoàn toàn là trường hợp ở đây).

Các ReadAsyncWriteAsync chức năng được định nghĩa như vậy mà họ không dùng mong muốn đọc vị trí dòng/ghi như họ Win32counterparts làm (một sự lựa chọn thiết kế rất nghèo theo ý kiến ​​của tôi), nhưng thay vào đó dựa vào vị trí hiện tại tổ chức bởi triển khai luồng. tình hình đó là tốt nếu một trong hai điều kiện tổ chức:

  1. ReadAsyncWriteAsync phải lấy vị trí con trỏ hiện tại để sử dụng bởi các hoạt động và cập nhật nó như thể hoạt động hoàn thành (hoặc không cập nhật nó ở tất cả) trước khi họ trở lại các Task hoặc
  2. Không có cuộc gọi nào tới ReadAsync hoặc WriteAsync có thể được thực hiện cho đến khi tất cả các cuộc gọi không đồng bộ trước đó đã được hoàn thành.

Bên ngoài hai điều kiện này, người gọi không bao giờ có thể chắc chắn về vị trí đọc hoặc viết sẽ xảy ra tại vì cấp phát hoạt động không đồng bộ có thể thay đổi vị trí của các dòng ở giữa bất kỳ Seek và gọi đến ReadAsync hoặc WriteAsync. Cả hai điều kiện này đều không được ghi nhận như là một yêu cầu, vì vậy tôi bị bỏ lại để tự hỏi nó hoạt động như thế nào.

thử nghiệm WhiteBox của tôi dường như chỉ ra rằng ít nhất là trong phiên bản FileStream của Stream, suối vị trí cập nhật không đồng bộ, điều này dường như chỉ ra rằng điều kiện thứ hai (chỉ có một cấp phát hoạt động cho phép) vẫn là một trong đó là cần thiết, nhưng điều đó có vẻ giống như một hạn chế nghiêm trọng (nó chắc chắn ngăn cản bất kỳ loại thực hiện thu thập phân tán nội bộ).

Có ai có thể cung cấp bất kỳ loại thông tin có thẩm quyền nào về việc giới hạn BeginRead cũ vẫn áp dụng cho ReadAsync hay không?

+1

Tôi nghĩ rằng logic đằng sau thiết kế là luồng là, bởi chính bản chất của nó, không phải là chủ đề an toàn; do đó nó không có ý nghĩa để truy cập nó trong khi đang hoạt động không đồng bộ (chỉ vì thao tác là không đồng bộ, cho phép mã của bạn để chờ đợi một cách duyên dáng trên luồng đọc/ghi mà không chặn, không có nghĩa là nên chơi với luồng từ một chuỗi khác trong khi hoạt động đó đang được tiến hành). – Cameron

+0

Cho rằng 'ReadAsync' sẽ đọc một số byte không xác định, làm sao nó có thể cập nhật chính xác vị trí trước khi thao tác hoàn tất? –

+0

IO đồng thời, ngay cả khi được bắt đầu tuần tự, có thể dẫn đến gọi lại được gọi đồng thời. Đó là một điều kiện chủng tộc cho hầu hết các triển khai luồng. Vì vậy, điều này không được phép nói chung. – usr

Trả lời

8

Bất kỳ ai có thể cung cấp bất kỳ loại thông tin có thẩm quyền nào về việc giới hạn cũ BeginRead vẫn áp dụng cho ReadAsync hay không?

Các giới hạn tương tự áp dụng cho BeginReadReadAsync.

Các phương pháp APM cũ không bị phản đối.Chúng vẫn được hỗ trợ đầy đủ và không có gì sai khi sử dụng chúng. Tuy nhiên, các phương pháp async dễ sử dụng hơn nên tài liệu đề xuất sử dụng chúng thay thế.

Tất cả những async "quá tải" bằng các lớp học cũ thường vẫn bao gồm gọi BeginXXXEndXXX hoặc nhiều nhất là cả hai lựa chọn gọi một phương thức chia sẻ (ví dụ FileStream.BeginReadAsync). Tôi chưa bao giờ thấy bất kỳ mã nào (trong khung hoặc cách khác) có các phương thức trình bao bọc APM trên một phương thức async.

Vì vậy, calling ReadAsync will result in calling BeginRead do đó, mọi giới hạn đều áp dụng cho cả hai. Hơn nữa, vì Stream không an toàn cho chủ đề và không quảng cáo như an toàn đồng thời (hơi khác một chút) nên bạn có thể an toàn không cho rằng bạn không thể yêu cầu đồng thời với yêu cầu async.

+0

Trong trường hợp không có tài liệu, tôi muốn có ít nhất một bình luận ở đâu đó trong mã nguồn chỉ ra hạn chế này, nhưng tôi cho rằng 30 phút nghiên cứu mã nguồn thô sẽ phải đủ. Cảm ơn! – James

+0

Tôi đã yêu thích nhận xét này trong hàm đó trên dòng 2023: 'Mã này cần được sửa. ' – James

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