wie bekommt man AfxRegisterWndClass thread safe?



  • Ich hab' hier eine MFC Applikation (VC++ 2005, also MFC 8.0), die mir gerade eben beim Initialisieren ne CResourceException geworfen hat.
    Dummerweise ist der Fehler nicht reproduzierbar, und aus dem Logfile sehe ich nur dass es ne CResourceException war, aber nicht wo sie hergekommen ist.

    Also hab' ich mir die Stellen in der MFC durchgesehen wo die Dinger geworfen werden. Meine Vermutung: ich rufe AfxRegisterWndClass in mehreren Threads auf, und AfxRegisterWndClass kommt damit nicht klar.

    Also dass AfxRegisterWndClass() damit nicht klar kommt ist keine Vermutung, das konnte ich verifizieren. Die Vermutung ist nur dass DAS auch wirklich das Problem bei dem Crash war, aber dabei könnt ihr mir natürlich nicht helfen.

    Frage: was sollte man machen wenn man AfxRegisterWndClass() in mehreren Threads aufrufen muss?

    Eigentlich gehe ich bei Funktionen die auf nem globalen State arbeiten ja davon aus dass die thread-safe sind. Scheint aber nicht so zu sein *grrr* - im Code von AfxRegisterWndClass bzw. AfxRegisterClass ist auch nichts zu sehen was hier zu thread-safety führen könnte.



  • Meine "beste" Idee im Moment wäre die AfxRegisterWndClass Aufrufe in

    AfxLockGlobals(CRIT_LOCKSHARED);
    ...
    AfxUnlockGlobals(CRIT_LOCKSHARED);
    

    einzuwickeln.

    Da das aber eher einfach nur so dahergeraten ist... dachte ich mir ich frag lieber mal nach.
    Vielleicht weiss ja einer der MFC Experten hier was das vernünftigste wäre.

    Oder... Variante 2:

    Ich könnte ganz auf AfxRegisterWndClass verzichten, und statt dessen AfxRegisterClass verwenden. Und selbst sicherstellen dass ich keine zwei Fensterklassen mit dem selben Namen registriere.

    Meinungen?


  • Mod

    Ja. Dumme Sache. Interessant, dass Du solch eine Race Condition hinbekommst.

    Ich habe AfxRegisterWndClass eigentlich noch nie verwendet.

    Ansonsten rufst Du es ja selber auf. Normalerweise in PreCreateWindow oder Create und eigentlich nur da. Die Frage ist ob Du Fremdsoftware hast die das benötigt oder macht.

    Es gibt also mehrere Methoden es zu beheben
    1. Bau eine Fehlerbehandlung ein...
    2. Synchronisere die Startphase (Main Window Erzeugung je Thread).

    Ich denke eine Fehlerbehandlung mit einem Retry ist das simpelste.



  • Ja, ich bekomme das hin 🙂
    Ich hab ein Splash-Window, und kurz darauf wird das Main-Window erzeugt.
    (Das Main-Window ist dabei danach dann etliche Sekunden invisible, während andere Sachen initialisiert werden die das Main-Window-Handle brauchen -- daher überhaupt das Splash-Window.)
    Das Splash-Window läuft in seinem eigenen Thread. Und das AfxRegisterWndClass() des Splash-Window und des Main-Window können so dann gleichzeitig laufen.

    Martin Richter schrieb:

    Ich habe AfxRegisterWndClass eigentlich noch nie verwendet.

    Ich verwende CS_HREDRAW|CS_VREDRAW . Ich könnte vermutlich auch in OnSize() Invalidate() aufrufen, aber da es CS_HREDRAW|CS_VREDRAW schon gibt...

    Ansonsten rufst Du es ja selber auf. Normalerweise in PreCreateWindow oder Create und eigentlich nur da. Die Frage ist ob Du Fremdsoftware hast die das benötigt oder macht.

    Nö, Fremdsoftware die mir da reinspielt hab' ich keine.

    Ich denke ich werde das ganze dann in eine eigene Funktion einwickeln, und da drinn einfach ne CRITICAL_SECTION locken. Retry kann ich dann immer noch einen machen, zwecks Paranoia-besänftigung 😉



  • Achja danke übrigens!
    Bei VC++ und MFC Fragen is auf dich (fast) immer Verlass. 👍


  • Mod

    hustbaer schrieb:

    Achja danke übrigens!
    Bei VC++ und MFC Fragen is auf dich (fast) immer Verlass. 👍

    Danke für das Lob!


Log in to reply