加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C:跨线程的错误处理问题

发布时间:2020-12-16 09:23:32 所属栏目:百科 来源:网络整理
导读:一般来说,我使用异常来处理错误,但是我在这里遇到的问题是错误适用于不同于导致错误的线程. 基本上,窗口有自己的线程,并且必须由创建窗口的同一线程创建并重置direct3d设备.但是,创建设备可能会失败,因此我需要在尝试创建实例的线程中抛出异常,而不是窗口代
一般来说,我使用异常来处理错误,但是我在这里遇到的问题是错误适用于不同于导致错误的线程.

基本上,窗口有自己的线程,并且必须由创建窗口的同一线程创建并重置direct3d设备.但是,创建设备可能会失败,因此我需要在尝试创建实例的线程中抛出异常,而不是窗口代码

回调函数:

void Callback(HWND hwnd,boost::function<void(HWND,LPARAM)> call,LPARAM lParam)
{
    //Make our stack allocated function object into a heap allocated one
    boost::function<void(HWND,LPARAM)> *callH = new boost::function<void(HWND,LPARAM)>(call);
    //send a message with a pointer to our function object in the WPARAM
    PostMessage(hwnd,WM_CALLBACK,(unsigned)callH,lParam);
}
LRESULT CALLBACK HookProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    //check for our custom message
    if(msg == WM_CALLBACK)
    {
        //retreive the function pointer from the WPARAM
        boost::function<void(HWND,LPARAM)> *callH = (boost::function<void(HWND,LPARAM)>*)wParam;
        //call it
        (*callH)(hwnd,lParam);
        //delete our heap allocated function object
        delete callH;
        return 0;
    }
    else
        //if there was nothing relevant to us,call the old message procedure
        return CallWindowProc(hooked[hwnd],hwnd,msg,wParam,lParam);
}
//std::map<HWND,WNDPROC> hooked;

请求窗口线程创建设备的代码

Graphics::Graphics(IWindow *_window,Size2<unsigned> _size)
:lost(false),reset(false),refCnt(0),backCol(0xFF000000),started(false),exited(false),window(_window),size(_size)
{
    window->AddRef();
    HWND hwnd = *((HWND*)window->GetHandle());
    CallbackHook(hwnd);
    Callback(hwnd,boost::bind(&Graphics::create,this),0);

    while(!started)Sleep(100);
}
void Graphics::create()
{
...code that may throw various exceptions
    started = true;
}

所以基本上我需要create()方法抛出的异常被创建Graphics对象的异常handelers捕获,这是另一个线程.

解决方法

也许你可以使用 Boost.Exception将调用包装在另一个函数中.

以下代码不起作用,但您可能会得到这个想法.

class Context
{
public:
    Context(HWND hwnd,const boost::function<void(HWND,LPARAM)>& f,LPARAM lParam)
    {
        // TODO: reroute call through Wrapper function.
    }

    void wait()
    {
        mutex::scoped_lock l(m);
        while (!finished)
        {
            c.wait(l);
        }
        if (ex)
            rethrow_exception(ex);
    }

private:
    void Wrapper()
    {
        try
        {
            f(/*params*/);
        }
        catch (...)
        {
            ex = current_exception();
        }
        mutex::scoped_lock l(m);
        finished = true;
        c.notify_all();
    }

    boost::function<void(HWND,LPARAM)> f;
    exception_ptr ex;
    bool finished;
    mutex m;
    condition c;
};

void Callback(HWND hwnd,LPARAM lParam)
{
    Context ctx(hwnd,f,lParam);

    ctx.wait();
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读