Правильный способ остановить асинхронный ISearchJob

#c #winapi #com #updates #wuapi

#c #winapi #com #Обновления #wuapi

Вопрос:

Я собираюсь использовать API WUA и начать выполнение асинхронного поиска обновлений таким образом:

 CComPtr<SearchCallbackImpl> iscc_; <<-- Note you need to CreateInstance
CComPtr<ISearchJob> pUpJob_;
pUpJob_ = NULL;

pUpSearcher_->BeginSearch(
        CComVariant(criteria.c_str()).bstrVal,
        iscc_,
        CComVariant(L"Scanning"),
        amp;pUpJob_);
  

Когда мне нужно остановить мою программу, но ISearchJob еще не завершен, я использую этот код:

 if (pUpJob_)
{
    CComVariant isStopped;
    pUpJob_->get_IsCompleted(amp;isStopped.boolVal);
    if (isStopped.boolVal == VARIANT_FALSE)
    {
        if (SUCCEEDED(pUpJob_->RequestAbort()))
        {
            pUpJob_->CleanUp();
            pUpJob_.Release();
        }
    }
}
  

Обычно этот код работает, но иногда он зависает pUpJob_->CleanUp(); , и у меня нет возможности правильно остановить мою программу.

Итак, мои вопросы:

  1. Каков правильный способ остановить асинхронное задание поиска обновлений?
  2. Также я неправильно понял, в чем разница между ISearchJob ::CleanUp и ISearchJob ::RequestAbort и как использовать эти методы, чтобы правильно остановить асинхронный поиск?
  3. Следует ли использовать эти методы вместе или по отдельности?

Ответ №1:

RequestAbort() также является асинхронным (подсказка на это есть в названии). После его вызова вы должны выполнить вызов pUpSearcher_->EndSearch() ; он вернет ISearchResult с ResultCode равным orcAborted , если прерывание было успешным. Затем вы можете освободить свои ресурсы.

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

Комментарии:

1. Я использую этот код в деструкторе моего класса, который оборачивает WUAPI.

2. Что будет, если я буду делать только pUpJob_->RequestAbort() без pUpSearcher_->EndSearch()

3. @SpaceRabbit просто любопытно, каково было ваше решение этой ситуации? Мой алгоритм делает это, когда поиск необходимо прервать из-за выхода из программы: (1) BeginSearch (2) RequestAbort (3) Очистка (4) НЕТ EndSearch . Проблема иногда в сбоях Cleanup()! Интересно, нужно ли вообще вызывать Cleanup при использовании RequestAbort?

4. @SpaceRabbit было бы здорово, если бы вы поделились своим окончательным решением этой проблемы здесь, в этой теме, поскольку сейчас я сталкиваюсь с аналогичной проблемой. Но в моем случае CleanUp() вылетает!