ISearchJob-> CleanUp застревает - PullRequest
       85

ISearchJob-> CleanUp застревает

0 голосов
/ 31 октября 2019

Я ищу асинхронно отсутствующие патчи через WUAPI. Я объявил объект ISearchJob (https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-isearchjob). Если я получаю тайм-аут от функции WaitForSingleObject, я вызываю RequestAbort (), затем выполняю CleanUp () объекта ISearchJob. Однако, когда я выполняю CleanUp, иногда это занимает больше15 минут. Знаете ли вы, почему? И есть ли какое-то решение для этого? Заранее спасибо за вашу помощь!


    // List of params that will be passed to the thread that will perform the actual search for missing updates
    typedef struct Params
    {
        CComPtr<IUpdateSearcher>& updateSearcher;
        CComPtr<ISearchResult>& searchResult;
        typeCharStr& criteria;
        CComObject<SearchCompleteFunction>* searchCompleteFunc; // needs to be released after usage
        CComPtr<ISearchJob>&& searchJob;
    };


// ptrUpdateSearcher, ptrSearchResult, bstrCriteria, searchCompleteFunc are already declared and configured when reaching this part of code
Params* stParams = new Params{ ptrUpdateSearcher, ptrSearchResult, bstrCriteria, searchCompleteFunc, nullptr };

    DWORD dwThreadId;
    HANDLE hThread = CreateThread( NULL, 0, searchForMissingPatchesThreadFunc, (LPVOID) stParams, 0, &dwThreadId );
    if( !hThread )
    {
        goto error;
    }

    // Start the thread and wait for finishing 
    DWORD dwRet = WaitForSingleObject( hThread, timeout > 0 ? timeout * 1000 : INFINITE ); 
    TerminateThread( hThread , 0 );
    CloseHandle( hThread );

    // Get the search result
    ptrSearchResult = stParams->searchResult;

    if( dwRet == WAIT_TIMEOUT )
    {
        // stop the ISearchJob
        stParams->searchJob->RequestAbort();
        stParams->searchJob->CleanUp(); // HERE GETS STUCK SOMETIMES EVEN FOR 15 MINUTES

        goto error;
    }

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ: Вот функция потока, COM инициализируется с COINIT_MULTITHREADED.

    // function that will asynchronously search for missing updates
    auto searchForMissingPatchesThreadFunc = [](LPVOID data) -> DWORD
    {
        // get the data from arguments
        Params *params = static_cast<Params*>( data );

        if (S_OK == params->updateSearcher->BeginSearch(_bstr_t(params->criteria.c_str()), params->searchCompleteFunc, CComVariant("Scanning"), &params->searchJob)
            && params->searchJob)
        {
            // Check if search is completed. If not, continue to check
            CComVariant isCompleted;
            params->searchJob->get_IsCompleted(&isCompleted.boolVal);

            while (isCompleted.boolVal == VARIANT_FALSE)
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(500));
                params->searchJob->get_IsCompleted( &isCompleted.boolVal ) ;
            }

            if (isCompleted.boolVal == VARIANT_TRUE)
            {
                // Search completed, get the result
                params->updateSearcher->EndSearch( params->searchJob, &params->searchResult );
            }
        }

        return 0;
    };

Я уже посмотрел на Правильный способ остановить асинхронный ISearchJob , если я вызываю EndSearch сразу после RequestAbort, проблема аналогична, но для ее завершения иногда требуется 15 минут. Я вызываю только RequestAbort (), программа завершится сбоем, когда поиск завершится (может быть в любое время от 5 секунд до 15 минут и более)

...