SDI: aus Workthread PostMessage zur CDoc: mit welchem handle?



  • Grüße an das Forum!

    Wenn es auch immer wieder Fragen zu threads gibt... ich frage trotzdem nochmal nach längerem Suchen.

    Wie also der topic sage: in einer SDI-Application möchte der Doc-Klasse die Nachricht schicken, dass der thread beendet ist. Nach diesem Beispiel z.B.: http://www.philosophicalgeek.com/2002/04/29/threads-in-mfc-i-worker-threads/ gehts ganz gut, aber nur in einem Dialog. Welches handel (oder was anderes?) kann/ muss man aber an eine Doc-Klasse schicken? Oder muss man das auf ganz andere Weise lösen?

    Der bisherige Code sieht so aus:

    #define WM_USER_THREAD_FINISHED (WM_USER+0x101)
    
    BEGIN_MESSAGE_MAP(CMFraksdiDoc, CDocument)
    	//{{AFX_MSG_MAP(CMFraksdiDoc)
    	ON_MESSAGE(WM_USER_THREAD_FINISHED, OnThreadFinished)
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    LRESULT CMFraksdiDoc::OnThreadFinished(WPARAM wParam, LPARAM lParam)
    {
    	// hier Behandlungssroutinen beim threadende...
    	return 0;
    }
    
    //diese Funktion wird von der statischen threatfunktion aus aufgerufen:
    void CMFraksdiDoc::rechnen()
    {
    //...
    //am Ende :
    
    	::PostMessage( ???? ,WM_USER_THREAD_FINISHED,0,0);
    }
    

    Vielen Dank im voraus und Grüße,
    Tobibe

    Edit:
    Ich beantworte das erstmal teilweise selber. Weil ich gestern Nacht unbedingt noch die Sache lösen musste, habe ich es etwas abgewandelt.

    Wenn man die Behandlung des thread-Endes in die View oder Mainfrm-Klasse verlegt, kann man an diese eine WS_Message schicken, indem man die handles für diese Fenster verwendet. Es gibt mit Sicherheit auch die Möglichkeit, das ohne handle zu machen und direkt an die doc-Klasse zu schicken... werd bei Gelegenheit nochmal genauer recherchieren.

    LG
    Tobibe


  • Mod

    Warum überhaupt eine Nachricht?

    1. Ein Doc ist kein Fenster und hat kein Handle.
    2. Eine WM_COMMAND Nachricht käme dennoch an, wenn das Dokument das aktive ist und bleibt. Bei einem SDI Projekt kann man davon ausgehen.
    3. Warum speicherst Du die Daten nicht direkt im Dokument über eine Methode.
    Einzig der Zugriff auf die Daten im Dokument müsste über eine CriticalSection abgesichert werden.
    4. Man kann auch eine Datenübergabe-Queue aufbauen. Nur diese wird gefüllt vom Thread und gelesen vom Dokument. Der Zugriff wird über eine CriticalSection abgesichert. Benachrichtigen kann man das Dokument über eine WM_COMMAND Nachricht.



  • Hallo Matrin,

    Es trat am Anfang folgendes Problem auf, weshalb ich an Nachrichtgen gedacht habe: Am Ende der Funktion wollte ich UpdateAllViews(NULL) aufgerufen. Aus dem selben thread herraus ist das kein Problem, wenn es aber aus einem workthread herraus aufgerufen wurde, kam es immer zu einem Laufzeitfehler. Meine Annahme war, dass diese Funktion nicht über verscheidene threads funktioniert.

    Mittlerweile habe ich noch eine andere Lösung gefunden: Der Arbeitsthread bekommt über AfxGetMainWnd() einen Zeiger auf den Mainfraim, und kann pFrame->RedrawWindow() aufrufen ... ohne Laufzeitfehler.

    Ich bin leider noch am Anfang von MFC, natürlich gibts immer verschiedene (und hierbei verschieden sichere) Methoden. Ich müsste natürlich noch eine CriticalSection implementieren, aber momentan wird auf die Daten (hauptsächlich wird nur 1 array beschrieben) von außerhalb nicht zugegriffen.

    Aber Danke für deine Hinweise, Martin, wenn ich an dem Projekt weiterarbeite, werde ich mich auch mal mit semaphoren &co befassen 🙂
    Grüße
    Tobibe


  • Mod

    Ich würde Dir eher raten ein WM_COMMAND mit PostMessage zu senden.
    Diese WM_COMMAND ID kanst Du in der MessageMap des Dialoges unterbringen.

    Dir ist klar, dass UpdateAlViews weitaus mehr machen kann als ein Redraw... 😉


Anmelden zum Antworten