8.4. Буферизация записи

TCP должен посылать данные пакетами. Размер пакетов может изменяться, но как правило он немногим менее 1 килобайта. Тем не менее, если TCP ожидает полного пакета данных, во многих случаях ответы могут быть не получены, поскольку запросы не были отосланы. TCP может использовать полные или неполные пакеты, Для неполных пакетов можно использовать алгоритм названый Nagle Coalescing. Nagle Coalescing внутренне буферизует данные, пока не будет достигнут указанный размер пакета или не истечет рассчитанное количество времени. Период времени обычно маленький и измеряется в миллисекундах.

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

Данные могут буферизироваться в строку и быть посланы за раз, тем не менее это требует писать дополнительный код и исключает использование всех методов записи во время буферизации. Это также может усложнить ваш код и увеличить потребности в памяти.

Вместо этого, вы можете использовать возможности Indy по буферизации записи. При использовании методов записи с буферизацией, вы можете позволить Indy буферизировать исходящие данные, что позволит вам использовать все возможные методы записи.

Для начала буферизации записи, вызовите метод OpenWriteBuffer и укажите размер буфера. Затем вы можете вызывать все функции записи в Indy, и весь вывод будет буферизироваться, пока буфер не будет заполнен. Каждый раз когда будет достигнут размер буфера, буфер посылается в соединение и очищается. Если размер буфера не указан, все данные буферизуются и должны быть вручную отправлены.

Имеется также несколько методов для управления буфером.

ClearWriteBuffer очищает текущий буфер и сохраняет буфер открытым. FlushWriteBuffer сбрасывает текущее содержимое и также сохраняет буфер открытым.

Для прекращения буферизации записи, вызовите CancelWriteBuffer или CloseWriteBuffer. CloseWriteBuffer записывает имеющие данные и заканчивает буферизацию записи, а CancelWriteBuffer закрывает буферизацию записи, без передачи.

8.5. Работа транзакций

Транзакции используются для определения единиц работы. Они называются рабочие транзакции и могут быть вложенными, и отделяют операции чтения и записи, которые могут быть одновременными. Рабочие транзакции обычно используются для отображения прогресса и состояния передачи.

Транзакции определены в Indy различными, предопределенными методами, такими как TIdHTTP.Get, WriteStream и так далее. Как пользователь, вы также можете определить свои собственные транзакции, с помощью BeginWork, DoWork и EndWork.

8.5.1. События OnWork

События OnWork состоят из трех событий и используется для связи состояний транзакций. Эти три события следующие: OnWorkBegin, OnWork и OnWorkEnd.

При начале транзакции возникает событие OnWorkBegin. В событие OnWorkBegin передаются Sender, WorkMode и WorkCount. Параметр Sender это соединение, к которому относится транзакция. Параметр WorkMode указывает режим работы – читающая или пишущая транзакция. Транзакции Read и Write могут возникать одновременно и транзакции могут быть вложенными. Параметр WorkCount указывает размер транзакции. Во многих транзакциях, размер не может быть определен, и в этом случае, WorkCount имеет значение 0. Иначе, WorkCount показывает количество байт. Обычно данное событие используется для отображения начала процесса.

Затем возникает серия событий OnWork. В событие OnWork передаются Sender, WorkMode и текущий WorkCount. Данное событие используется для отображения прогресса.

Когда транзакция заканчивает, возникает событие OnWorkEnd. В событие OnWorkEnd OnWork передаются только Sender и WorkMode. Данное событие используется для отображения завергения процесса.

8.5.2. Управление своими собственными рабочими транзакциями

Вы можете создавать свои собственные транзакции, вызывая BeginWork, DoWork и EndWork. Параметры те же самые, что описанны выше. Вызовы вложенных транзакций обслуживаются автоматически.

Для выполнения транзакции, сначала вызовите BeginWork с указанием размера, если он известен. Затем вызовайте DoWork для отображения прогресса. По окончанию вызовите EndWork.

 

Hosted by uCoz