Поделиться через


Реализация метода FlushQueues

Область применения: Outlook 2013 | Outlook 2016

Диспетчер spooler MAPI использует метод IXPLogon::FlushQueues для скачивания и отправки всех ожидающих сообщений поставщику транспорта и от него. Как правило, диспетчер очереди MAPI сбрасывает очереди для всех поставщиков транспорта, которые вошли в сеанс, начиная с первого поставщика транспорта, заданного в разделе порядка транспорта профиля пользователя. Очистка очередей почти всегда является результатом прямого запроса со стороны пользователя, поэтому отправка и получение сообщений во время очистки очередей синхронно с диспетчером очереди. Так как эти вызовы синхронны, поставщик транспорта должен обработать их как можно быстрее.

Поставщики транспорта должны обработать вызов FlushQueues , как описано в следующей последовательности шагов, чтобы обеспечить правильную обработку сообщений и включить использование внешних ресурсов, таких как модемы, другими поставщиками транспорта в рамках операции FlushQueues диспетчера очереди MAPI.

Шаг Компонент Реализация
1. Диспетчер очереди MAPI
Вызывает метод FlushQueues для первого поставщика транспорта, указанного в порядке транспорта профиля пользователя, передавая запрошенные флаги в параметре ulFlags . FlushQueues вызывается один раз со всеми флагами, установленными для всей операции отправки и скачивания.
2. Поставщик транспорта
Необходимо выполнить ряд действий перед возвращением из вызова FlushQueues . Если ранее отправленные сообщения откладываются, следует вызвать метод IMAPISupport::SpoolerNotify с установленным флагом NOTIFY_SENT_DEFERRED. Обратите внимание, что диспетчер очереди MAPI может отменить сообщение, которое было отложено до того, как поставщик транспорта может завершить обработку сообщения. Если поставщик транспорта использует внешний ресурс, например модем, необходимо установить подключение к внешнему ресурсу. Бит STATUS_OUTBOUND_FLUSH в свойстве PR_STATUS_CODE (PidTagStatusCode) строки состояния поставщика транспорта должен быть задан с помощью метода IMAPISupport::ModifyStatusRow . Поставщик транспорта должен вернуть S_OK для вызова FlushQueues .
3. Диспетчер очереди MAPI
Проверяет строку состояния поставщика транспорта для бита STATUS_OUTBOUND_FLUSH и вызывает IXPLogon::SubmitMessage для первого сообщения в очереди.
4. Поставщик транспорта
Обрабатывает сообщение и возвращается из вызова SubmitMessage .
5. Диспетчер очереди MAPI
Если поставщик транспорта возвращает S_OK из SubmitMessage, диспетчер очереди MAPI вызывает IXPLogon::EndMessage для сообщения, как и при обычной отправке сообщений. Если поставщик транспорта возвращает значение, отличное от S_OK из SubmitMessage, диспетчер очереди MAPI обрабатывает значение соответствующим образом перед вызовом EndMessage или перед повторным вызовом SubmitMessage .
6. Поставщик транспорта
Возвращается из EndMessage с состоянием обработки сообщений в параметре lpulFlags .
7. Диспетчер очереди MAPI и поставщик транспорта
Цикл SubmitMessage- EndMessage продолжается до тех пор, пока не будут загружены все сообщения в очереди.
8. Диспетчер очереди MAPI
Уведомляет поставщика транспорта о завершении скачивания сообщений путем вызова метода IXPLogon::TransportNotify поставщика транспорта с установленным флагом NOTIFY_END_OUTBOUND_FLUSH.
9. Поставщик транспорта
Освобождает все внешние ресурсы, используемые при отправке исходящих сообщений, чтобы их могли использовать другие поставщики транспорта для очистки очередей. Бит STATUS_INBOUND_FLUSH в свойстве PR_STATUS_CODE строки состояния поставщика транспорта должен быть задан с помощью ModifyStatusRow.
10. Диспетчер очереди MAPI
Проверяет строку состояния поставщика транспорта для бита STATUS_INBOUND_FLUSH и вызывает IXPLogon::StartMessage , если она задана.
11. Поставщик транспорта
Обрабатывает сообщение и возвращается из StartMessage. Если у поставщика транспорта есть другие сообщения для отправки, он должен вызвать SpoolerNotify с установленным флагом NOTIFY_NEWMAIL. Если у поставщика транспорта нет сообщений для отправки, он должен вызвать IMAPIProp::SaveChanges для сообщения, переданного диспетчером очереди MAPI в StartMessage и возвращаемом .
12. Диспетчер очереди MAPI
Продолжает вызывать StartMessage до тех пор, пока в сообщении не будет вызван метод SaveChanges . После завершения отправки поставщиком транспорта диспетчер очереди MAPI вызывает TransportNotify с установленным флагом NOTIFY_END_INBOUND_FLUSH.
13. Поставщик транспорта
Очищает бит STATUS_INBOUND_FLUSH в свойстве PR_STATUS_CODE строки состояния с помощью ModifyStatusRow и освобождает все внешние ресурсы, чтобы они были доступны для использования другими поставщиками транспорта.
14. Диспетчер очереди MAPI
Вызывает FlushQueues для следующего поставщика транспорта, указанного в порядке транспорта профиля пользователя.

Если клиентское приложение вызывает IMAPIStatus::FlushQueues для объекта состояния поставщика транспорта, поставщик транспорта должен задать соответствующий бит в строке состояния с параметром ModifyStatusRow. Затем диспетчер очереди MAPI вызывает метод IXPLogon::FlushQueues поставщика транспорта в удобном для диспетчера очереди MAPI. При вызове метода IXPLogon::FlushQueues поставщика транспорта в результате вызова IMAPIStatus::FlushQueues клиентского приложения операция выполняется асинхронно для клиентского приложения. В противном случае IXPLogon::FlushQueues работает синхронно с диспетчером очереди MAPI.

По соображениям производительности диспетчер очереди MAPI будет вызывать метод FlushQueues поставщика транспорта, только если в строке состояния поставщика транспорта заданы флаги STATUS_INBOUND_FLUSH и STATUS_OUTBOUND_FLUSH. Следовательно, поставщик транспорта может остановить операцию FlushQueues в любое время, очислив флаги STATUS_OUTBOUND_FLUSH и STATUS_INBOUND_FLUSH в строке состояния. Если диспетчер очереди MAPI завершает работу и должен завершить операцию FlushQueues , он вызывает TransportNotify с установленными флагами NOTIFY_END_INBOUND_FLUSH и NOTIFY_END_OUTBOUND_FLUSH. Поставщик транспорта должен освободить все внешние ресурсы и вернуться.