Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在UI线程中创建对话框导致崩溃_C++_Multithreading - Fatal编程技术网

C++ 在UI线程中创建对话框导致崩溃

C++ 在UI线程中创建对话框导致崩溃,c++,multithreading,C++,Multithreading,我试图在UI线程(CWinThread)中创建一个对话框。 但是,当调用CDialog::Create()时,它会崩溃。 我已经用以前的实现验证过,对话框是在非线程模式下成功创建的 这里有没有大师知道在CWinThread中创建对话框的崩溃原因 无螺纹: class CProduction : public CDialog{ ... } class CScrollProductionView : public CScrollView{ CProduction *m_pProduction; ..

我试图在UI线程(CWinThread)中创建一个对话框。 但是,当调用CDialog::Create()时,它会崩溃。 我已经用以前的实现验证过,对话框是在非线程模式下成功创建的

这里有没有大师知道在CWinThread中创建对话框的崩溃原因

无螺纹:

class CProduction : public CDialog{
...
}
class CScrollProductionView : public CScrollView{
CProduction *m_pProduction;
...
}

void CScrollProductionView::OnInitialUpdate(){
   m_pProduction = new CProduction(0, *m_pVisionAdapter);
   m_pProduction->Create(IDD_DLG_PROD, this);  //--> created dialog successfully
   m_pProduction->ShowWindow(SW_SHOW);
}
实现UI线程:

class CProduction : public CDialog{
...
}
class CScrollProductionView : public CScrollView{
  CProductionThread* m_pProdThread;
  ...
}

class CProductionThread : public CWinThread{
   CProduction *m_pProduction;
   ...
}

void CScrollProductionView::OnInitialUpdate(){
   m_pProdThread->PostThreadMessage(WM_INITPRODTHREADMESSAGE, PROD_INIT, (LPARAM)m_pVisionAdapter);
   m_pProdThread->PostThreadMessage(WM_INITPRODTHREADMESSAGE, PROD_CREATE_DLG, (LPARAM)this);

 }

void CProductionThread::InitMessageHandler(WPARAM wParam, LPARAM lParam)
{
   printf("Receiving InitMessageHandler msg %d\n", (UINT)wParam);
   switch(wParam)
   {
    case PROD_INIT:
    {
      CVisionAdapter* pAdapter = (CVisionAdapter*)lParam;
      m_pProduction = new CProduction(NULL, *pAdapter);
    }
     break;
    case PROD_CREATE_DLG:
     {
      CScrollProductionView* pView = (CScrollProductionView*)lParam;
      m_pProduction->Create(IDD_DLG_PROD, pView);  //--> Crash here
      m_pProduction->ShowWindow(SW_SHOW);
     }
       break;
     default:
       break;
   }
}
错误消息:

调试断言失败
档案:。。。。wincore.cpp
电话号码:9906


感谢您查看此问题。

崩溃是由MFC在创建过程中引用无效的窗口句柄(作为父级传入)引起的

一般来说,线程可以访问 只有它创建的MFC对象。这 是因为暂时和永久 Windows句柄映射保存在线程中 本地存储有助于维护 防止同时访问 来自多个线程

MSDN中所述的一个简单修复方法是将代码更改为

...

m_pProdThread->PostThreadMessage(WM_INITPRODTHREADMESSAGE, PROD_CREATE_DLG, (LPARAM)this->GetSafeHwnd());

...

CScrollProductionView* pView = (CScrollProductionView*)CScrollProductionView::FromHandle((HWND)lParam);
m_pProduction->Create(IDD_DLG_PROD, pView);
m_pProduction->ShowWindow(SW_SHOW);
编辑

修复了指向msdn的链接。

崩溃是由MFC在创建过程中引用无效的窗口句柄(作为父级传入)引起的

一般来说,线程可以访问 只有它创建的MFC对象。这 是因为暂时和永久 Windows句柄映射保存在线程中 本地存储有助于维护 防止同时访问 来自多个线程

MSDN中所述的一个简单修复方法是将代码更改为

...

m_pProdThread->PostThreadMessage(WM_INITPRODTHREADMESSAGE, PROD_CREATE_DLG, (LPARAM)this->GetSafeHwnd());

...

CScrollProductionView* pView = (CScrollProductionView*)CScrollProductionView::FromHandle((HWND)lParam);
m_pProduction->Create(IDD_DLG_PROD, pView);
m_pProduction->ShowWindow(SW_SHOW);
编辑

修复了指向msdn的链接。

我怀疑问题在于处理
PROD\u CREATE\u DLG
消息时未创建您的
CProduction
对象。这可能是因为使用了
PostThreadMessage
。使用
PostThreadMessage
充满了问题。特别是,消息可能会丢失,因此线程永远不会看到
PROD_INIT
消息

在单线程代码中,您在
create
调用之前创建
CProduction
对象。为什么不在多线程代码中执行相同的操作

如果您真的想使用windows消息在线程之间进行通信,我将创建一个“仅消息”窗口(请参阅),因为窗口消息不会以与线程消息相同的方式丢失


或者,使用线程安全队列在线程之间传递自定义消息,例如我在

的示例队列。我怀疑问题在于,在处理
PROD\u CREATE\u DLG
消息时,您的
CProduction
对象尚未创建。这可能是因为使用了
PostThreadMessage
。使用
PostThreadMessage
充满了问题。特别是,消息可能会丢失,因此线程永远不会看到
PROD_INIT
消息

在单线程代码中,您在
create
调用之前创建
CProduction
对象。为什么不在多线程代码中执行相同的操作

如果您真的想使用windows消息在线程之间进行通信,我将创建一个“仅消息”窗口(请参阅),因为窗口消息不会以与线程消息相同的方式丢失


或者,使用线程安全队列在线程之间传递自定义消息,例如我在

的示例队列。如果类之间有很多通信,例如传递对象指针、字符串等,请尝试不要创建CWinThread,而不要创建工作线程。

如果通过消息处理更新GUI,您会感觉不那么头痛。

如果类之间有很多通信,如传递对象指针、字符串等,请不要创建CWinThread,而不要创建工作线程。

如果通过消息处理更新GUI,您会感觉不那么头痛。

wincore.cpp第9906行的断言是什么?通常情况下,断言代码本身或附近的注释会给出一个很大的错误线索。wincore.cpp第9906行的断言是什么?通常情况下,断言代码本身或附近的注释会给出一个很大的错误提示。@wengseng中的“如果您有一个多线程应用程序,该应用程序以除使用CWinThread对象之外的其他方式创建线程,您无法从该线程访问其他MFC对象…”这是怎么回事?我能够模拟我这边的崩溃,这在发布的修改后得到修复。“如果你有一个多线程应用程序,它以一种不同于使用CWinThread对象的方式创建线程,你不能从该线程访问其他MFC对象…”来自@wengseng,你那边的结果如何?我能够模拟我这边的碰撞,这是在发布修改后修复的。