Являются ли Stream.ReadAsync и Stream.WriteAsync предположительно, чтобы изменить положение курсора синхронно перед возвратом или после завершения операции?
Я пытаюсь реализовать Stream
, который поддерживает ReadAsync
и WriteAsync
, и с учетом запаздывания documentation, Я изо всех сил пытаюсь понять, как это сделать правильно. В частности, относительно позиции курсора потока. Аналогичный вопрос был задан здесь и здесь относительно старой функции BeginRead
. Документация для этой функции, по-видимому, указывала на то, что BeginRead
не следует вызывать снова до тех пор, пока не будут выполнены ожидающие асинхронные операции.
Учитывая, что BeginRead
теперь устарело больше не рекомендуется для новой разработки и Stream
имеет вероятность были значительно изменены для реализации новых функций Async, все еще неясно. (EDIT: Обычно этот вид предупреждения означает, что новые функции реализованы напрямую, а старые функции вызывают новые и остаются только для обратной совместимости, но это, похоже, не совсем так).
Функции ReadAsync
и WriteAsync
определены так, что они не принимают желаемую позицию потока чтения/записи в качестве Win32 counterparts делают (очень плохой выбор дизайна, на мой взгляд), но вместо этого полагаются на текущую позицию, связанную с реализацией потока. Эта ситуация прекрасна, если выполнено одно из двух условий:
-
ReadAsync
и WriteAsync
должны захватить текущую позицию курсора для использования этой операцией и обновить ее, как если бы операция была завершена (или вообще не обновлена) до того, как они вернут Task
или
- Вызов
ReadAsync
или WriteAsync
невозможен, пока все предыдущие асинхронные вызовы не будут завершены.
За пределами этих двух условий вызывающий абонент никогда не может быть уверен в позиции чтения или записи, поскольку ожидающие асинхронные операции могут изменить положение потока между любыми Seek
и вызвать ReadAsync
или WriteAsync
. Ни одно из этих условий не документировано как требование, поэтому мне остается задаться вопросом, как он должен функционировать.
Мое тестирование whitebox, по-видимому, указывает на то, что по крайней мере для версии FileStream
Stream
позиция потока обновляется асинхронно, что, как представляется, указывает на то, что второе условие (разрешено только одной ожидающей операции) требуется, но это кажется серьезным ограничением (это, безусловно, исключает любую внутреннюю реализацию сбора рассеяния).
Может ли кто-нибудь предоставить какую-либо авторитетную информацию относительно того, применяется ли прежнее ограничение BeginRead
к ReadAsync
или нет?
Ответы
Ответ 1
Может ли кто-либо предоставить какую-либо авторитетную информацию относительно того, применяется ли прежнее ограничение BeginRead
к ReadAsync
или нет?
Те же ограничения применяются для BeginRead
и ReadAsync
.
Старые методы APM не устарели. Они все еще полностью поддерживаются, и нет ничего плохого в их использовании. Однако методы async
значительно проще в использовании, поэтому в документации предлагается использовать их.
Все эти async
"перегрузки" на этих старых классах обычно по-прежнему состоят из вызова BeginXXX
и EndXXX
или не более двух параметров вызывают общий метод (например, FileStream.BeginReadAsync
). Я никогда не видел никакого кода (в рамках или иначе), у которого есть методы обертки APM над async
.
Следовательно, вызов ReadAsync
приведет к вызову BeginRead
, поэтому любое ограничение применимо к обоим. Кроме того, поскольку Stream
не является потокобезопасным и не рекламирует себя как совместимый с одновременным использованием (это немного отличается), можно с уверенностью предположить, что вы не можете наводнить его с помощью запросов async
одновременно.