Как правильно использовать CountChanged из цикла Idle
Как я должен использовать Fetch в событии CountChanged из цикла Idle? Я видел демо, где есть комментарий, чтобы отменить цикл простоя.
Однако, если я сделаю это -
async void CountChanged(...)
{
await Task.Run(() => idleToken.Cancel())
Fetch(...)
}
Извлечение будет выполняться асинхронно и, возможно, после любого события MessageExpunge. Это может испортить локальный индекс, который может ожидать, что CountChange уже обновил индекс локального кэша.
- 4 УДАЛИТЬ
- 3 EXISTS - событие CountChange здесь может быть выполнено после * 3 EXPUNGE ниже, и это испортит индекс
- 3 УДАЛИТЬ
Пожалуйста посоветуй?
2 ответа
Это проблема не только простоя. Это относится к каждой команде, которая может выдавать незапрошенный ответ EXISTS. То, что я сделал, вместо того, чтобы выполнять код из обработчиков событий, я использую CommandQueue, где я добавляю действия, которые представляют собой код, который должен выполняться внутри обработчиков событий. После выполнения команды Mailkit / Imap я выполняю действия CommandQueue в том же порядке, в котором я синхронно получал их в одном и том же потоке. В целом библиотека Mailkit очень приятная и поздравляю с отличной работой.
Проще всего использовать 2 экземпляра ImapClient. Тот, который просто выполняет IDLE, и тот, который выполняет выборку при изменении количества сообщений.
Ваш другой вариант:
void CountChanged (object sender, EventArgs e)
{
countChanged = true;
idleToken.Cancel ();
}
Затем:
await client.IdleAsync (idleToken, cancelToken);
if (countChanged) {
client.Fetch (...);
}