Console.WriteLine("Файл {0} переименован в\n{1}",

 e.OldFullPath, e.FullPath);

}

Чтобы проверить работу этой программы, запустите приложение и откройте Проводник Windows. Попытайтесь переименовать, создать, удалить файлы *.txt в MyFolder или выполнить с ними какие-то другие действия, вы увидите, что консольное приложение реагирует на эти действия выводом различной информации о состоянии текстовых файлов (рис. 16.10).

Исходный код. Проект MyDirectoryWatcher размещен в подкаталоге, соответствующем главе 16.

Рис. 16.10. Наблюдение за текстовыми файлами

<p>Асинхронный файловый ввод-вывод</p>

В завершение нашего обзора пространства имен System.IO давайте выясним, как осуществляется асинхронное взаимодействие с типами FileStream. Один из вариантов поддержки асинхронного взаимодействия в .NET вы уже видели при рассмотрении многопоточных приложений (см. главу 14). Ввиду того, что ввод-вывод может занимать много времени, все типы, производные от System.IO.Stream, наследуют множество методов, разрешающих асинхронную обработку данных. Как и следует ожидать, эти методы работают в связке с типом IAsyncResult.

public abstract class System.IO.Stream: MarshalByRefObject, IDisposable {

 public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state);

 public virtual IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state);

 public virtual int EndRead(IAsyncResult asyncResult); public virtual void EndWrite(IAsyncResult asyncResult);

}

Работа с асинхронными возможностями типов, производных от System. IO.Stream, аналогична работе с асинхронными делегатами и асинхронными удаленными вызовами методов. Маловероятно, что асинхронный подход может существенно улучшить доступ к файлам, но есть большая вероятность того, что от асинхронной обработки получат выгоду другие потоки (например, использующие сокеты). Так или иначе, следующий пример иллюстрирует подход, в рамках которого вы можете асинхронно взаимодействовать с типом FileStream.

class Program {

 static void Main(string[] args) {

  Console.WriteLine("Старт первичного потока, ThreadID = {0}", Thread.CurrentThread.GetHashCode());

  // Следует использовать этот конструктор, чтобы получить

  // FileStream с асинхронным доступом для чтения и записи.

  FileStream fs = new FileStream('logfile.txt", FileMode.Append, FileAccess.Write, FileShare.None, 4096, true);

  string msg = "это проверка";

  byte[] buffer = Encoding.ASCII.GetBytes(msg);

  // Начало асинхронной записи.

  // По окончании вызывается WriteDone.

  // Объект FileStream передается методу обратного вызова,

  // как информация состояния.

  fs.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(WriteDone), fs);

 }

 private static void WriteDone(IAsyncResult ar) {

  Console.WriteLine("Метод AsyncCallback для ThreadID = {0}", Thread.CurrentThread.GetHashCode());

  Stream s = (Stream)ar.AsyncState;

  s.EndWrite(ar);

  s.Close();

 }

}

Единственным заслуживающим внимания моментом (при условии, что вы помните основные особенности использования делегатов!) в этом примере является то, что для разрешения асинхронного поведения типа FileStream вы должны использовать специальный конструктор (который здесь и используется). Последний параметр System.Boolean (если он равен true) информирует объект FileStream о том, что соответствующие операции должны выполняться во вторичном потоке.

Исходный код. Проект AsynсFileStream размещен в подкаталоге, соответствующем главе 16.

<p>Резюме</p>
Перейти на страницу:

Похожие книги