Подтвердить что ты не робот

При использовании FileStream.ReadAsync() следует открыть файл в режиме async?

Старый .Net способ выполнения асинхронного ввода-вывода для FileStream заключается в использовании FileStream.BeginRead() и FileStream.EndRead().

Документация MSDN для FileStream.BeginRead() гласит:

FileStream предоставляет два разных режима работы: синхронный ввод-вывод и асинхронный ввод-вывод. Хотя любой из них может быть использован, базовые ресурсы операционной системы могут позволить доступ только в одном из этих режимов.

По умолчанию FileStream синхронно открывает дескриптор операционной системы. В Windows это замедляет асинхронные методы. Если используются асинхронные методы, используйте конструктор FileStream (String, FileMode, FileAccess, FileShare, Int32, Boolean).

Способ .Net 4.5x для асинхронного ввода-вывода для FileStream заключается в использовании Stream.ReadAsync().

Документация MSDN для FileStream.ReadAsync() связана непосредственно с документацией для Stream.ReadAsync(). В этой документации нет необходимости открывать файл в режиме async; действительно, пример кода в документации явно не делает этого.

Поэтому я предполагаю, что при использовании File.ReadAsync() нет необходимости открывать файл в асинхронном режиме.

Правильно ли это предположение?

[EDIT]

Я только что обнаружил статью MSDN об использовании Async для доступа к файлам.

Это означает:

В примерах в этом разделе используется класс FileStream, который имеет параметр, который вызывает асинхронный ввод-вывод на уровне операционной системы. Используя эту опцию, во многих случаях можно избежать блокировки потока ThreadPool.

Чтобы включить эту опцию, вы указываете useAsync = true или options = FileOptions.Asynchronous аргумент в вызове конструктора.

Итак, теперь я думаю, что я должен открыть файл в асинхронном режиме... Если это так, то несколько неудачно, что пример кода, приведенный в документации для ReadAsync(), не открывает файл асинхронно!

4b9b3361

Ответ 1

В win32 вам нужно указать FILE_FLAG_OVERLAPPED, чтобы использовать асинхронный File IO. В мире .net вы используете параметр isAsync FileStream для достижения того же. Если вы этого не сделаете, операции не будут асинхронными.

Жаль, что FileStream.ReadAsync и связанные с ним методы не смогли его документировать.

Вы можете подтвердить это, заглянув в реализацию.

public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
   ...
    if (!this._isAsync || !Environment.IsWindowsVistaOrAbove)
    {
        return base.ReadAsync(buffer, offset, count, cancellationToken);
    }
    ...
    return stateObject;
}

base.ReadAsync в конечном итоге вызовет метод Stream.Read синхронно в ThreadPool, показывая, что операция isync, но на самом деле нет.

Дополнительная информация из Параллельное программирование в Windows (стр. 818):

Как и в случае с CreateFile, во время создания необходимо указать, что вы как использовать FileStream для асинхронного выполнения. С FileStream, вы делаете это, передавая true как аргумент isAsync для перегрузки конструктора, которые его принимают. Поток isAsyncсвойство впоследствии вернет true. Если вы не пройдете этот значение, вызовы BeginRead и BeginWrite будут успешными. Но они будет использовать реализацию базового класса из Stream, которая обеспечивает ни одно из преимуществ истинного асинхронного ввода-вывода файлов.

Выше информация о методах APM (так как это старая книга), но все еще актуальна.