首页 > 解决方案 > ISearchJob->CleanUp 卡住了

问题描述

我正在通过 WUAPI 异步搜索丢失的补丁。我已经声明了一个 ISearchJob 对象(https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-isearchjob)。如果我从 WaitForSingleObject 函数收到超时,我调用 RequestAbort() 然后执行 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 的正确方法,如果我在 RequestAbort 之后立即调用 EndSearch,问题类似,但有时仍需要 15 分钟才能完成。如果我只调用 RequestAbort(),程序将在搜索完成时崩溃(可能是 5 秒到 15 分钟或更长时间)

标签: c++comatlwuapi

解决方案


推荐阅读