2017-02-04 78 views
3

我有以下代码访问共享数据:从工作线程

void COrganizerProgressDlg::LaunchWorkerThread() 
{ 
    CWorkerData data; 
    data.m_pWndOrganizerProgressDlg = this; 
    data.m_pWndImageOrganizerDlg = m_pWndImageOrganizerDlg; 
    ::AfxBeginThread(RunBackgroundWorker, &data); 
} 

这里是我的RunBackgroundWorker()方法,这是一个static方法。

UINT COrganizerProgressDlg::RunBackgroundWorker(LPVOID pParam) 
{ 
    try 
    { 
     // Run organizer engine 
     COrganizerEngine engine(m_nNotifyMessage, (CWorkerData*)pParam); 
     engine.Run(); 
    } 
    catch (CException *e) 
    { 
     e->ReportError(); 
     e->Delete(); 
    } 
    return 0; 
} 

的数据被用在我的工人阶级初始化设置。

问题是我的data变量在调用AfxBeginThread()之前包含有效数据,但似乎在RunBackgroundWorker()中包含垃圾。

我错过了什么?我如何从我的工作线程访问这些数据?

回答

3

data是具有自动存储持续时间的对象。一旦超出范围,它就不再有效。我假设,data超出范围之前,工作线程有机会拿起信息。

为了解决这个基本上有两种选择:

  • 创建同步对象(例如CEvent),并具有工作线程信号,它,当完成读出该数据。在主线程中调用WaitForSingleObject来阻止执行,直到发生这种情况。这受制于死锁,例如当工作者线程死亡时。
  • 更简单的解决方案是使用动态内存管理。使用new分配CWorkerData实例并将该地址传递给工作线程。工作线程可以随时调用delete,只要它完成对象。
+0

D'oh!忘记了这里的自动存储时间。感谢您让我回到正轨。我一直在使用'CEvent',但我还不太满意。想想也许我应该多阅读一下。 –

+0

@JonathanWood:使用同步对象涉及更多,并且仅适用于工作线程在整个生命周期中不需要信息的情况。您发布的代码看起来并非如此。我会选择第二种方式,并完全转让数据的所有权。工作线程可以决定什么时候清理。 – IInspectable

+0

是的,我做过。我复制了一些代码,尽管它使用'CEvent'来处理用户取消操作。只是好像我应该明白,好一点。 –