超出范围的C++多线程对象

超出范围的C++多线程对象,c++,multithreading,C++,Multithreading,我正在从一个UI事件分离类启动一个在新类中编写的工作线程。现在,当从主UI线程创建新的工作线程时,它将立即从控件返回,从而导致工作线程类对象被销毁。通过检查下面的代码可以找到更好的解释 //class - UI void CUIClass::button_click() { CDataProcess obj; obj.Start(); } //class - DataProcess CDataProcess::CDataProcess() { } CDataProcess::~C

我正在从一个UI事件分离类启动一个在新类中编写的工作线程。现在,当从主UI线程创建新的工作线程时,它将立即从控件返回,从而导致工作线程类对象被销毁。通过检查下面的代码可以找到更好的解释

//class - UI  
void CUIClass::button_click()
{
  CDataProcess obj;
  obj.Start();
}

//class - DataProcess
CDataProcess::CDataProcess()
{
}

CDataProcess::~CDataProcess()
{
}

void CDataProcess::Start()
{
  CWinThread *pThread = AfxBeginThread(DataProcessingThread, this);
}

UINT CDataProcess::DataProcessingThread()
{
  //some processing
}
现在我想到的一些可能的解决方案是:

使“CDATA进程对象;”UI类的成员,因此它不会超出范围。但我故意把它放在本地。 在UI类button_事件中使用WaitForSignalObject来等待工作线程完成信号或在工作类中编写等待函数。
还有什么合适的解决方案呢?

好吧,如果你每次点击按钮都要打开一个线程,我认为你需要重新考虑,那么线程池在这里最合适。 基本上,您希望在一个函数中编写onClick逻辑,该函数可以调用其他函数和对象,当然这将是onClick事件的回调函数。然后要求线程池异步执行回调


您可能还想了解std::async,它可以异步启动函数,但请记住,如果线程很重,您可能还是希望使用线程池。

这取决于您试图实现的目标。很明显,您需要创建一个工作对象,它的寿命比按钮单击回调的时间长:

CDataProcess* obj = new CDataProcess();
obj->Start();

假设您的名字是AfxBeginThread,那么您就处于更为特定的Windows MFC环境中。您可以再次使用任何任务池技术,这取决于您试图实现的目标。连接点、线程池——由你来命名。您需要如何检测任务何时完成?如何向用户显示它?您是否允许用户取消任务?等等等等。

嗯,我想我给自己制造了一些严重的麻烦。我应该坚持使用单独类中的DataProcess功能,该类可以从UI类启动的线程调用。这样就解决了每一个问题

您有责任确保CDATA进程实例在线程之外。把它作为局部变量是没有意义的。无论你想把它保留在本地,你都必须重新考虑它。阻塞UI线程,直到工作线程完全完成,这就违背了将工作线程放在首位的目的;如果您愿意这样做并冻结UI,只需在UI线程上执行相同的工作即可;for wait your working thread in main thread.OT:除非您需要MFC提供的特定内容,否则您可以始终使用VS2013支持的版本。我只使用MFC线程。你能提供调用Start的代码吗?然后函数结束,obj超出范围,你有内存泄漏。除了不能以任何方式终止创建的线程之外,请确保您必须进一步跟踪此对象。怎样基本上取决于线程模型。我不能推荐,但你可以做的就是删除它,如果你需要一个比{}作用域更长的对象,那就由你来管理它。你永远不会删除它!这是一种危险的做法@DavidHaim您完全可以删除此项,您认为引用计数对象是如何实现的?@DavidHaim随机发现:。很抱歉弄破了你的泡泡。那么,让线程成为按钮的成员变量,或者更好,创建一个管理线程的类,按钮将包含它