wxThread - thread stürzt beim 2. starten ab



  • Hi,
    ich habe hier ein Problem mit der Klasse wxThread, wenn ich den thread das erste Mal starte funktioniert alles super, beim zweiten Mal stürzt das Programm ab.
    Ich starte und beende den thread über einen start und stop button.
    Hier der Quellcode:

    class MyThread : public wxThread
    {
        public:
            MyThread(wxTextCtrl* text_){ text = text_; }
            void* Entry();
    
        private:
            wxTextCtrl* text;
    
    };
    
    void* MyThread::Entry()
    {
        do
        {
            text->AppendText("Thread is working..\n");
    
            wxThread::Sleep(50);
        }
        while(! TestDestroy());
    
        return NULL;
    }
    
    class Gui : public wxFrame
    {
        public:
            Gui();
            const bool CreateThread();
            void KillThread();
    
        private:
            wxMenuBar* menu;
            wxMenu* file;
            wxButton* start;
            wxButton* stop;
            wxTextCtrl* text;
            void OnStart(wxCommandEvent &event);
            void OnStop(wxCommandEvent &event);
            void OnExit(wxCommandEvent &event);
            MyThread* thread;
    
            enum MenuControls
            {
                idStart = 1000,
                idStop,idExit
            };
    
            DECLARE_EVENT_TABLE()
    };
    
    BEGIN_EVENT_TABLE(Gui, wxFrame)
        EVT_BUTTON(idStart, Gui::OnStart)
        EVT_BUTTON(idStop, Gui::OnStop)
        EVT_MENU(idExit, Gui::OnExit)
    END_EVENT_TABLE()
    
    Gui::Gui() : wxFrame(NULL, wxID_ANY, wxT("Threads"), wxDefaultPosition, wxSize(600,400))
    {
        this->menu = new wxMenuBar();
        this->file = new wxMenu();
        this->file->Append(idExit, wxT("E&xit\tCtrl-F4"));
        this->menu->Append(file, wxT("&File"));
        this->SetMenuBar(menu);
        this->text = new wxTextCtrl(this, wxID_ANY, wxT(""), wxPoint(0,30), wxSize(590,315), wxTE_PROCESS_ENTER | wxTE_MULTILINE);
    
        this->start = new wxButton(this,idStart,wxT("Start"), wxPoint(150,5), wxDefaultSize, 0);
        this->stop = new wxButton(this,idStop,wxT("Stop"), wxPoint(370,5), wxDefaultSize, 0);
    }
    
    const bool Gui::CreateThread()
    {
        if(! thread)
        {
            thread = new MyThread(text);
        }
    
        switch(thread->Create())
        {
            case wxTHREAD_NO_ERROR:
                thread->SetPriority(WXTHREAD_DEFAULT_PRIORITY);
                thread->Run();
                return true;
    
            case wxTHREAD_NO_RESOURCE:
    
            case wxTHREAD_RUNNING:
                return false;
    
            default: return false;
        };
    }
    
    void Gui::KillThread()
    {
        if(thread)
        {
            thread->Delete();
            text->AppendText("Thread beendet!");
        }
    }
    
    void Gui::OnStart(wxCommandEvent &event)
    {
        CreateThread();
    }
    
    void Gui::OnStop(wxCommandEvent &event)
    {
        KillThread();
    }
    
    void Gui::OnExit(wxCommandEvent &event)
    {
        this->Destroy();
    }
    
    class MainApp : public wxApp
    {
        public:
            virtual bool OnInit();
    };
    
    bool MainApp::OnInit()
    {
        Gui* main = new Gui();
        main->Show(true);
    
        return true;
    }
    
    IMPLEMENT_APP(MainApp)
    


  • Hi,
    du solltest niemals GUI-Operationen aus einem anderen Thread als dem Mainthread machen. Das wird auch in der Doku gesagt und führt zu Problemen, wie du sie gerade hast. Also las diesen Versuch auf diese Weise gleich ganz sein, denn das wird nicht funktionieren. Versuche stattdessen vom Thread aus Events an den Mainthread zu schicken, über den dann entsprechende Änderungen am GUI vorgenommen werden.

    Gruß



  • Niemals schrieb:

    Hi,
    du solltest niemals GUI-Operationen aus einem anderen Thread als dem Mainthread machen. Das wird auch in der Doku gesagt und führt zu Problemen, wie du sie gerade hast. Also las diesen Versuch auf diese Weise gleich ganz sein, denn das wird nicht funktionieren. Versuche stattdessen vom Thread aus Events an den Mainthread zu schicken, über den dann entsprechende Änderungen am GUI vorgenommen werden.

    Gruß

    erstmal danke für deine Antwort!
    Ich weiß nich ob ich dich richtig verstanden habe. Ich habe verstanden, dass ich den Text in dem Textfeld nicht von meinem erstellten Thread aus ändern darf.
    Ich habe das jetzt folgendermaßen geändert, führt aber zu dem gleichen Problem.

    class MyThread : public wxThread
    {
        public:
            MyThread(){ }
            void* Entry();
    
    };
    
    void* MyThread::Entry()
    {
        do
        {
            wxMessageBox("Thread is working..\n");
    
            wxThread::Sleep(2000);
        }
        while(! TestDestroy());
    
        return NULL;
    }
    

  • Mod

    Auch ne MessageBox ist GUI.
    Auch solltest du den MyThread Pointer wieder auf 0 nach dem Löschen setzen...



  • phlox81 schrieb:

    Auch ne MessageBox ist GUI.
    Auch solltest du den MyThread Pointer wieder auf 0 nach dem Löschen setzen...

    Vielen du hast mir sehr geholfen, es funktioniert jetzt alles!


Anmelden zum Antworten