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 neCResourceException
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, undAfxRegisterWndClass
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 inAfxLockGlobals(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 dessenAfxRegisterClass
verwenden. Und selbst sicherstellen dass ich keine zwei Fensterklassen mit dem selben Namen registriere.Meinungen?
-
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 dasAfxRegisterWndClass()
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 inOnSize() Invalidate()
aufrufen, aber da esCS_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.
-
hustbaer schrieb:
Achja danke übrigens!
Bei VC++ und MFC Fragen is auf dich (fast) immer Verlass.Danke für das Lob!