如何在CWorkerThread中编写简单的后台线程 [英] How to write simple background thread in CWorkerThread

查看:257
本文介绍了如何在CWorkerThread中编写简单的后台线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图异步运行功能在我的插件Internet Explorer(我正在写的BHO在VC ++)。如建议这里我尝试使用CWorkerThread。

I'm trying to asynchronously run function in my add-on for Internet Explorer (I'm writing BHO in VC++). As suggested here I'm trying to use CWorkerThread.

我一直在尝试数小时,但仍然不知道如何做到。我在ATL没有太多的经验。在互联网上缺少一个好的文档或教程正在杀我。

I've been trying to figure it out for hours but still have no idea how to do it. I don't have much experience in ATL. The lack of a good documentations or tutorials on Internet is killing me.

我通过Add-> Class创建类并选择ATL Simple Object(这是怎么添加类的ATL项目的?)。但是如何实现这个IWorkerThreadClient?我认为在类视图中选择Add-> Implement Interface会很好,但是列表中没有IWorkerThreadClient。

I'm creating class by Add->Class and choosing ATL Simple Object (that's how you add classed to ATL project right?). But how to implement this IWorkerThreadClient? I thought that choosing Add->Implement Interface in Class View would be good but there is no IWorkerThreadClient on the list.

我想我不知道ATL或COM enaugh但不能找到良好的资源学习这个(esspessialy ATL7)。

I think I don't know ATL or COM enaugh but can't find good resource for learning this (esspessialy newest ATL7).

我甚至尝试过winapi CreateThread 方法,但它不工作。我通过这个类指针来运行静态方法,但是有些东西随着内存的破坏。但是如果它工作我仍然宁愿使用 CreateThread

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 memory later. Nevertheless if It had worked I still would rather use something else than CreateThread.

现在我有类似< a href =http://msdn.microsoft.com/en-us/library/bb250489%28VS.85%29.aspx =nofollow>此。在 OnDocumentComplete 中有 RemoveImages(sptmlDoc),我只想要异步运行它。

Right now I have something like this. In OnDocumentComplete there's RemoveImages(sptmlDoc) and I just want to run it asynchronously.

编辑 CreateThread

我试过运行RemoveImages函数(来自这里< a>)。我在我的类中创建了静态函数,其签名为此处。 RemoveImages有参数,因此我将它复制到类的成员:

I tried running RemoveImages function (from here) asynchronously. I created static function in my class with signature like here. RemoveImages has parameter so I copied it to a member of a class:

if (htmlDoc2 != NULL)
{
    m_tmpHtmlDocument2 = htmlDoc2;
    m_hThread = CreateThread( NULL, 0, MyThreadFunction, this, 0, &m_threadId);
}

MyThreadFunction

static DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 
{ 
    CHelloWorldBHO* myClass = (CHelloWorldBHO*)lpParam;
    myClass->RemoveImages(myClass->m_tmpHtmlDocument2);

    return 0; 
}

我得到未处理的异常0x60c0da05在iexplore.exe:0xC0000005:读取位置0x000001b8。这里以粗体线:

I get "Unhandled exception at 0x60c0da05 in iexplore.exe: 0xC0000005: Access violation reading location 0x000001b8." here in the bold line:


void CHelloWorldBHO::DontDisplayElement(CComPtr htmlElement)
{
    CComPtr style;
    HRESULT hr = htmlElement->get_style(&style);

    if (hr == S_OK && style != NULL)
    {       
        static const CComBSTR strNone(L"none");
        style->put_display(strNone);
    }
}


推荐答案

通过尝试使用在另一个线程中的1个线程中分配的COM句柄来执行调皮。 BHO环境是STA(单线程公寓),因此您应该编组 m_tmpHtmlDocument2 对象以在您的线程中使用。

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已经表明,在某些情况下,IE可能让你逃避将浏览器com对象从1线程传递到另一个线程,然后获取文档和元素之后可能工作。这是完全不可靠的。

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.

根据IE 6/7/8,你将有不同的目标线程来执行你的操作,思考每个安全级别/框架/ tab / window。基本上任何时候IE创建一个新的网站

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'

此外,为了防止您的应用程序的网页活动,即使导航离开页面后,在FireFox你会使用 nsWeakPointer<> ,我从来没有在IE中找到equivelant。

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.

建议:也许而不是marshalling com另一个线程,因为您与网页的互动缓慢,尝试改善您与网页的互动方式并提高进程的性能可能是一个更好的目标。

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.

这里是一个大纲使用CThreadPool将队列请求,然后在池有空间时执行它们。

我使用 pvWorkerParam 将线程绑定到站点。

我有不同类型的 ActionRequests ,你当然可以简化并为请求传递null。

注意:此操作无法解决您已拥有的编组问题

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() );
  }
}

这篇关于如何在CWorkerThread中编写简单的后台线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆