Oberflächenänderungen über Threads



  • Hallo,
    ich bekomme bei meinem Programm eine Runtime Exception mit der Überschrift "Debug Assertion Failed!". Eine Exception Nummer oder sonstige Angaben gibt es leider nicht.

    Sie wird geworfen, wenn ich von einem Thread die Oberfläche ändern will.
    Also Aufbau:
    Hauptklasse, die von einer Klasse abgleitet wurde, die die Oberfläche bereitstellt.
    Diese Hauptklasse startet einen Thread und übergibt "this".
    Der Thread ruft eine Funktion von dem übergebenen "this" auf, um die Oberflöche zu verändern.

    Ich habe mir Datei wincore.cpp, in der die Exception geworfen wird, genauer angeschaut:

    Die Exception wird in der Zeile geworfen:

    ASSERT((CWnd*)p == this);
    

    Darunter steht:

    // Note: if either of the above asserts fire and you are
    // writing a multithreaded application, it is likely that
    // you have passed a C++ object from one thread to another
    // and have used that object in a way that was not intended.
    // (only simple inline wrapper functions should be used)
    //
    // In general, CWnd objects should be passed by HWND from
    // one thread to another.  The receiving thread can wrap
    // the HWND with a CWnd object by using CWnd::FromHandle.
    //
    // It is dangerous to pass C++ objects from one thread to
    // another, unless the objects are designed to be used in
    // such a manner.
    

    Nun wollte ich es mit diesem HWND versuchen. Leider steht in der Hauptklasse in m_hWnd NULL. Ich habe gelesen, das hwnd wird erzeugt, wenn der CWnd-Konstruktor über create aufgerufen wird.

    Leider habe ich darauf keinen Einfluss, da ich mich nicht um das CWnd kümmere. Für die Oberfläche nutze ich eine Klasse der Entwicklungsumgebung (ich schreibe nur ein PlugIn für diese Umgebung). Diese bindet CWnd ein.

    Habt ihr eine Idee, wie ich dieses Problem angehen kann?

    Im Release Modus funktioniert es wunderbar.
    Kann ich etwas einbauen, mit dem die Zeile mit der Oberflächenänderung nur im Releasemodus ausgeführt wird? Das wäre zwar nicht optimal aber damit könnte ich leben.

    Danke für eure Hilfe



  • falls dies im falschen Forum ist, könnt ihr es auch gerne verschieben


  • Mod

    CWnd Zeiger kann man Cross Threads nicht einfach so verwenden.
    Sicher ist eigentlich nur der Zugriff auf m_hWnd.

    Wenn Du eine andere Methode aufrufst wird das Fenster in er aktuellen Window-Map des Threads gesucht, dort wirdkeine Eintrag gefunden und es kommt zu diesem ASSERT.

    Änderungen an der UI sollten tunlichst über Threadgrenzen vermieden werden. Das führt leicht zu Deadlocks. Sende eine Nachricht per PostMessage an den Mainthread und der soll die UI Änderungen machen. Wenn SendMessage verwendet werden muss, dann muss der primäre UI Thread auch sicher Nachrichten in der Messageloop abholen.



  • da nur die methode der hauptklasse zeichen hätte sollen wollte ich dadurch die synchronisation gewährleisten.

    aber ich habe es nun mit postmessage umgesetzt.

    vielen dank für den tipp


Anmelden zum Antworten