2016-02-26 3 views
0

Простите мое невежество, но я с проблемами понимания отрывок MSDN для чтения содержимого файла асинхронноЧтение текстового файла асинхронно

https://msdn.microsoft.com/en-us/library/jj155757.aspx

string text = await ReadTextAsync(filePath); 

...

private async Task<string> ReadTextAsync(string filePath) 
{ 
    using (FileStream sourceStream = new FileStream(filePath, 
     FileMode.Open, FileAccess.Read, FileShare.Read, 
     bufferSize: 4096, useAsync: true)) 
    { 
     StringBuilder sb = new StringBuilder(); 

     byte[] buffer = new byte[0x1000]; 
     int numRead; 
     while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0) 
     { 
      string text = Encoding.Unicode.GetString(buffer, 0, numRead); 
      sb.Append(text); 
     } 

     return sb.ToString(); 
    } 
} 

Как что чтение асинхронно? Похоже, дождаться завершения ReadTextAsync, чтобы вернуть содержимое. Если в этом методе вставлен Thread.Sleep, он будет ждать завершения, и после вызова метода этот код не будет работать.

+0

Это асинхронный из-за 'ожидания sourceStream.ReadAsync'. Обратите внимание, что асинхронный не означает, что вы не ждете, это означает, что вы не привязываете поток, пока вы ждете, если вы решите подождать. – juharr

+0

Как вы на самом деле читаете содержимое содержимого асинхронно? Вы не можете вызвать этот метод и продолжить выполнение программы. – tic

+0

* Этот * метод «ждет» ответа, но система потребления может свободно выполнять другие действия, пока эта задача завершается. '" Вы не можете вызвать этот метод и продолжить выполнение программы "' - вы, безусловно, можете, и это именно то, что делает система. Например, когда пользовательский интерфейс продолжает отображать и отвечать во время выполнения метода. Это приложение продолжает делать что-то. – David

ответ

0

Проблема заключалась в отсутствии понимания от меня о модификаторе async. Исходный пример выполняется асинхронно, но любой дополнительный медленный код завершения, добавленный в этот метод, будет работать синхронно и ждать завершения вызывающего потока. Если бы действительно был нужен Sleep, тогда весь вызов мог быть завернут в новый Task и вызван, возвращая задачу, а не результат.

Это не приостанавливает выполнение программы, например, когда вы читаете внешний диск.

public Task<string> ReadTextAsync(string filePath) 
    { 
     var task = new Task<string>(() => 
     { 
      Thread.Sleep(5000); 
      using (FileStream sourceStream = new FileStream(filePath, 
FileMode.Open, FileAccess.Read, FileShare.Read, 
bufferSize: 4096, useAsync: true)) 
      { 
       StringBuilder sb = new StringBuilder(); 

       byte[] buffer = new byte[0x1000]; 
       int numRead; 
       while ((numRead = sourceStream.Read(buffer, 0, buffer.Length)) != 0) 
       { 
        string text = Encoding.ASCII.GetString(buffer, 0, numRead); 
        sb.Append(text); 
       } 

       return sb.ToString(); 
      } 
     }); 
     task.Start(); 
     return task; 
    } 
1

В оболочке гайки await убедитесь, что для операций ввода-вывода (например, запросы к базе данных, чтения файлов, записи в сети и т. Д.), Что поток отсылается обратно на O/S, в то время как код ожидает результата на завершение порт. Таким образом ваши потоки или не сидят вокруг indling, ожидая завершения ввода-вывода, теперь они могут повторно использоваться O/S для других действий. По завершении ввода/вывода O/S переназначает новый поток ИЛИ использует исходный поток (в зависимости от ConfigureAwait), чтобы возобновить операцию.

Так что это не параллельное или параллельное программирование, оно просто позволяет потоку обслуживать другие запросы, пока процесс (кодовая точка) ждет завершения ввода-вывода.

Также см. Asynchronous Programming with Async and Await для получения дополнительной информации.

+0

А, это объясняет это. Я должен добавить затем к моему вопросу, как мне получить метод, который можно одновременно вызвать для чтения содержимого файла и продолжить выполнение? – tic

+0

@tick - это совсем другое дело. Я думаю, вам нужно разделить длину файла на диапазоны начала и конца, назначить несколько потоков на каждый диапазон и открыть FileStream как только без чтения, просто прочитайте их диапазон , и у вас есть какой-то окончательный процесс, который снова объединяет его. Это говорит о том, что вы, вероятно, увидите преимущество 0, потому что вы читаете с того же диска, и O/S может обслуживать только одно чтение из одного файла за раз, чтобы ваша бутылочная горловина по-прежнему была вводом-выводом. Это, вероятно, не стоило бы усилий для создания. – Igor

Смежные вопросы