Я использую wxWidgets, и я вызываю функцию, которая занимает много времени для продолжения. Я хотел бы сделать это в фоне.
Как я могу сделать это?
Спасибо за справку
Я работал с потоками в wxWidgets практически всеми способами, описанными здесь , и я могу сказать, что использование настраиваемых событий, хотя изначально было немного сложнее, избавит вас от головной боли в долгосрочной перспективе. (Класс wxMessageQueue довольно хорош, но когда я его использовал, то обнаружил, что он протекает; хотя я не проверял его около года.)
Базовый пример:
MyFrm.cpp
#include "MyThread.h"
BEGIN_EVENT_TABLE(MyFrm,wxFrame)
EVT_COMMAND(wxID_ANY, wxEVT_MYTHREAD, MyFrm::OnMyThread)
END_EVENT_TABLE()
void MyFrm::PerformCalculation(int someParameter){
//create the thread
MyThread *thread = new Mythread(this, someParameter);
thread->Create();
thread->Run();
//Don't worry about deleting the thread, there are two types of wxThreads
//and this kind deletes itself when it's finished.
}
void MyFrm::OnMyThread(wxCommandEvent& event)
{
unsigned char* temp = (unsigned char*)event.GetClientData();
//do something with temp, which holds unsigned char* data from the thread
//GetClientData() can return any kind of data you want, but you have to cast it.
delete[] temp;
}
MyThread. h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <wx/thread.h>
#include <wx/event.h>
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_MYTHREAD, -1)
END_DECLARE_EVENT_TYPES()
class MyThread : public wxThread
{
public:
MyThread(wxEvtHandler* pParent, int param);
private:
int m_param;
void* Entry();
protected:
wxEvtHandler* m_pParent;
};
#endif
MyThread.cpp
#include "MyThread.h"
DEFINE_EVENT_TYPE(wxEVT_MYTHREAD)
MyThread::MyThread(wxEvtHandler* pParent, int param) : wxThread(wxTHREAD_DETACHED), m_pParent(pParent)
{
//pass parameters into the thread
m_param = param;
}
void* MyThread::Entry()
{
wxCommandEvent evt(wxEVT_MYTHREAD, GetId());
//can be used to set some identifier for the data
evt.SetInt(r);
//whatever data your thread calculated, to be returned to GUI
evt.SetClientData(data);
wxPostEvent(m_pParent, evt);
return 0;
}
Мне кажется, что это гораздо более ясный и лаконичный пример, чем тот, который предлагает вики. Очевидно, я пропустил код, касающийся фактического запуска приложения (соглашение wx сделало бы это MyApp.cpp) и любой другой код, не связанный с потоками.
Если вам просто нужно, чтобы что-то работало в фоновом режиме до тех пор, пока оно не будет завершено - пожар и забыть, если хотите, что-то вроде этого:
// warning: off the top of my head ;-)
class MyThread
: public wxThread
{
public:
MyThread() : wxThread(wxTHREAD_DETACHED)
{
if(wxTHREAD_NO_ERROR == Create()) {
Run();
}
}
protected:
virtual ExitCode Entry()
{
// do something here that takes a long time
// it's a good idea to periodically check TestDestroy()
while(!TestDestroy() && MoreWorkToDo()) {
DoSaidWork();
}
return static_cast<ExitCode>(NULL);
}
};
MyThread* thd = new MyThread(); // auto runs & deletes itself when finished