Próbuję wdrożyć Stream
, który obsługuje ReadAsync
i WriteAsync
, i biorąc pod uwagę spareseness z documentation, mam trudności, aby zrozumieć, jak to zrobić prawidłowo. Konkretnie, w odniesieniu do pozycji kursora strumienia. Podobne pytanie zostało zadane here i here dotyczące starej funkcji BeginRead
. Dokumentacja tej funkcji zdawała się wskazywać, że nie powinno się ponownie wywoływać BeginRead
, dopóki nie zakończą się żadne oczekujące operacje asynchroniczne.Czy Stream.ReadAsync i Stream.WriteAsync mają zmienić synchronicznie pozycję kursora przed powrotem lub po zakończeniu operacji?
Zważywszy, że BeginRead
jest teraz przestarzałeno longer recommended for new development i Stream
, najprawdopodobniej znacząco zmienione w celu wdrożenia nowych funkcji ASYNC rzeczy są ponownie niejasny. (EDYCJA: Zwykle tego rodzaju ostrzeżenie oznacza, że nowe funkcje są zaimplementowane bezpośrednio, a stare funkcje wywołują nowe i są nadal dostępne dla kompatybilności wstecznej, ale wydaje się, że tak nie jest w tym przypadku).
The ReadAsync
WriteAsync
i funkcje są określone tak, że nie biorą one żądaną pozycję odczytu strumienia/zapisu jako ich Win32counterparts zrobić (bardzo słaby wybór projektu moim zdaniem), ale zamiast polegać na aktualnej pozycji posiadanych przez implementacja strumienia. Taka sytuacja jest w porządku, jeśli jeden z dwóch warunków przytrzymanie:
ReadAsync
iWriteAsync
musi chwycić bieżącą pozycję kursora do wykorzystania przez operację i aktualizować go tak, jakby operacja zakończona (lub nie aktualizuje go w ogóle), zanim wrócąTask
lub- Nie można wykonywać żadnych połączeń, dopóki wszystkie poprzednie połączenia asynchroniczne nie zostaną zakończone.
Poza tymi dwoma warunkami, rozmówca nigdy nie może być pewny stanowiska odczytu lub zapisu nastąpi przy ponieważ w toku operacji asynchronicznych mogą zmieniać pozycję strumienia pomiędzy każdym Seek
i zadzwonić do ReadAsync
lub WriteAsync
. Żaden z tych warunków nie jest udokumentowany jako wymóg, więc zastanawiam się, jak powinien funkcjonować.
Moje testy strukturalne wskazuje na to, że przynajmniej w wersji Stream
FileStream
, strumień pozycja aktualizuje asynchronicznie, co wydaje się wskazywać, że drugi warunek (tylko jeden czeka operacja dozwolone) jest jeszcze jeden, który jest wymagany, ale wydaje się to poważnym ograniczeniem (z pewnością wyklucza to wszelkiego rodzaju wewnętrzną implementację scatter-gather).
Czy każdy może podać jakiekolwiek wiarygodne informacje, czy stare ograniczenie w postaci BeginRead
nadal ma zastosowanie do , czy też nie?
Myślę, że logika stojąca za projektem polega na tym, że strumień ze swej natury nie jest bezpieczny dla wątków; dlatego nie ma sensu, aby uzyskać do niego dostęp podczas gdy operacja asynchroniczna jest w toku (tylko dlatego, że operacja jest asynchroniczna, pozwalając na to, aby twój kod z wyczekiwaniem oczekiwał na odczyt/zapis strumienia bez blokowania, nie oznacza, że dobrym pomysłem jest granie z strumień z innego wątku, podczas gdy ta operacja jest w toku). – Cameron
Biorąc pod uwagę, że 'ReadAsync' odczyta nieznaną liczbę bajtów, w jaki sposób może dokładnie zaktualizować pozycję przed zakończeniem operacji? –
Równoczesne operacje wejścia, nawet jeśli są inicjowane sekwencyjnie, mogą powodować, że wywołanie zwrotne będzie wywoływane jednocześnie. To warunek wyścigowy dla większości wdrożeń strumieniowych. Jest to ogólnie zabronione. – usr