Mô hình sau đây của các cuộc gọi đa luồng có thể chấp nhận được .Net FileStream?Yêu cầu đồng bộ hóa cho FileStream. (Bắt đầu/Kết thúc) (Đọc/Ghi)
Một số đề gọi một phương thức như thế này:
ulong offset = whatever; // different for each thread
byte[] buffer = new byte[8192];
object state = someState; // unique for each call, hence also for each thread
lock(theFile)
{
theFile.Seek(whatever, SeekOrigin.Begin);
IAsyncResult result = theFile.BeginRead(buffer, 0, 8192, AcceptResults, state);
}
if(result.CompletedSynchronously)
{
// is it required for us to call AcceptResults ourselves in this case?
// or did BeginRead already call it for us, on this thread or another?
}
đâu AcceptResults
là:
void AcceptResults(IAsyncResult result)
{
lock(theFile)
{
int bytesRead = theFile.EndRead(result);
// if we guarantee that the offset of the original call was at least 8192 bytes from
// the end of the file, and thus all 8192 bytes exist, can the FileStream read still
// actually read fewer bytes than that?
// either:
if(bytesRead != 8192)
{
Panic("Page read borked");
}
// or:
// issue a new call to begin read, moving the offsets into the FileStream and
// the buffer, and decreasing the requested size of the read to whatever remains of the buffer
}
}
Tôi đang bối rối vì các tài liệu dường như không rõ ràng đối với tôi. Ví dụ: lớp FileStream cho biết:
Bất kỳ thành viên tĩnh công cộng nào thuộc loại này đều an toàn. Bất kỳ thành viên cá thể nào cũng không được bảo đảm là luồng an toàn.
Nhưng tài liệu cho BeginRead dường như chiêm nghiệm có nhiều yêu cầu đọc trong chuyến bay:
Nhiều yêu cầu không đồng bộ đồng thời làm cho yêu cầu đặt hàng hoàn thành bấp bênh.
Nhiều lần đọc có được phép bay không? Viết? Đây có phải là cách thích hợp để đảm bảo vị trí của số Position
của luồng giữa cuộc gọi đến Tìm kiếm và cuộc gọi đến BeginRead
không? Hay khóa đó cần phải được giữ tất cả các cách để EndRead
, do đó chỉ có một lần đọc hoặc viết trong chuyến bay tại một thời điểm?
Tôi hiểu rằng việc gọi lại sẽ xảy ra trên một chuỗi khác và việc xử lý của tôi là state
, buffer
sẽ xử lý theo cách cho phép nhiều chuyến bay đọc.
Hơn nữa, có ai biết nơi nào trong tài liệu để tìm câu trả lời cho những câu hỏi này không? Hoặc một bài báo được viết bởi ai đó trong biết? Tôi đã tìm kiếm và không thể tìm thấy bất cứ điều gì.
tài liệu liên quan:
FileStream class
Seek method
BeginRead method
EndRead
IAsyncResult interface
Chỉnh sửa với một số thông tin mới
Kiểm tra nhanh với Reflector cho thấy BeginRead không ghi vị trí luồng vào trạng thái cho mỗi cuộc gọi (một số trường của cấu trúc NativeOverlapped). Có vẻ như EndRead không tham khảo vị trí luồng, ít nhất là không theo bất kỳ cách rõ ràng nào. Đây không phải là kết luận, rõ ràng, bởi vì nó có thể là một cách không rõ ràng hoặc nó có thể không được hỗ trợ bởi các API cơ bản.
+1 Câu hỏi hay. – SLaks