How to write simple background thread in CWorkerThread

孤街醉人 提交于 2019-12-04 16:37:51

Your performing a naughty by trying to use a COM handle allocated in 1 thread in another. BHO environment is STA (Single Threaded Apartment) so you should be marshalling the m_tmpHtmlDocument2 object for use in your thread.

Experiance has shown that in some cases IE may let you get away with passing the Browser com object from 1 thread to another and then getting the document and elements afterwards may work. This is entirely unreliable.

Depending on IE 6/7/8 you will have different target threads to execute your actions on, thinking at the levels of per security level/frame/tab/window. basically any time IE creates a new 'Site'

Also to prevent your app from holding the pages active even after navigation away from the page, in FireFox you would use an nsWeakPointer<> , I've never found the equivelant in IE.

Suggestion: Perhaps instead of marshalling com to another thread because your interaction with the page is slow, trying to improve the way you interact with the page and improve performance in process might be a better aim.

Here is an outline using the CThreadPool which will queue up requests, and then execute them when the pool has space.
I use pvWorkerParam to tie the threads back to the site.
I have different types of ActionRequests, you could of course simplify and just pass null for the request.
Note: This doesn't resolve marshalling issues you already have

class ActionRequest{ 
  DontDisplayElement();// define your do stuff in here 
};

class ScriptWorker
{
public:
ScriptWorker(void);
virtual ~ScriptWorker(void);

public:
BOOL Initialize(void* pvWorkerParam);
void Execute(ActionRequest *request, void* pvWorkerParam, OVERLAPPED* pOverlapped){
try{
       std::auto_ptr<ActionRequest> cleanupRequest(request);
       request.DontDisplayElement();
    } catch(...) {}
    }
void Terminate(void* pvWorkerParam);

private:
boolean m_bCoUninit;
};

Site{
  CThreadPool<ScriptWorker> m_scriptWorkerThread;
  Site() {
    void *pvWorkerParam = this;// or whatever you want to have passed to every script worker and execute in the pool.
    m_scriptWorkerThread.Initialize( pvWorkerParam, 1 );
  }
  OnDocumentComplete() {
    m_scriptWorkerThread.QueueRequest( new ActionRequest() );
  }
}

and sptmlDoc - is it an IHTMLDocumet* ?

IWorkerThreadClient - never heard of it

"I even tried winapi CreateThread approach but it isn't working. I'm passing this class pointer to run static method but something is corrupting with memomory later"

Keeping it simple is the best design pattern of them all. So stick with CreateThread unless you have good reasons not to. Now, my guess is that the crash occurs because of sptmlDoc being passed to the thread for later processing. The thing is such pointers are only valid from the BeforeNavigate event until DocumentComplete event. Try to do that processing on the spot (inside your event handler) and see if it stil crashes. Some code posting would help too

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!