einfaches thread



  • ich habe versucht etwas zu verstehen von OnIdle......no chance..
    ich bin doch kein profi .

    wie rufe ich task1 und task2 ..

    kannst du mein beispiel einsetzen

    wäre nett wenn ja



  • Das taskt1, tastk2 ist nur ein Bsp

    long lNumber = 1; // unsere Zahl (hab ich jetzt global definiert, kannst aber auch einfach eine Membervariable deiner CWinApp Klasse nehmen)
    BOOL CMyApp::OnIdle(LONG lCount) 
    { 
       lNumber++; // Zahl um eins erhöhen
       if (lNumber == 1000000) // lNumber ist jetzt genau eine Milllionen
       {
           // tue etwas
       }
       if (lNumber < 1000000)
           return TRUE; // OnIdle soll wieder ausgeführt werden
       else
           return FALSE; // wir brauchen kein OnIdle mehr
    }
    

    Müsste so funktionieren. Da ich OnIdle noch nie verwendet habe (da ich lieber mit Threads arbeite), weiß ich nicht, in welchen Abständen OnIdle normalerweiße aufgerufen wird (hab keine Erfahrung damit). Musst du halt mal ausprobieren.



  • OnIdle wird dann aufgerufen, wenn das Fenster gerade nichts zu tun hat.
    Wenns ne ca. konstante Zeit sein soll dann WM_TIMER aufrufen, wobei man auch hier beachten muss, dass diese Nachricht geringe Priorität hat und daher bei der Zeitangabe ein "MINDESTENS so lange warten" gilt. Dürfte aber für dieses Problem vollkommen ausreichen



  • sorry rapha

    ich verstehe nicht.
    warum rufe ich OnIdle denn wenn von 1 bis 1000 000 wird nicht gemacht ausser flase zurück geben.

    ich sage dir meine frage nochmal.

    ich habe ein dialog mit einem knopf . wenn ich den knopf klicken startet eine schelife oder process die zählt von 1 bis 10000000 für 1000 000 mal.

    ich will daß mein dialog wärend des prossezes kann man andere knopf deucken oder das fenster verschieben.

    ich habe seit gestern rumpropiert leider kein erfolg.



  • dokdok schrieb:

    warum rufe ich OnIdle denn wenn von 1 bis 1000 000 wird nicht gemacht ausser flase zurück geben.

    Aus der MSDN:

    OnIdle performs some processing and returns a nonzero value to indicate it should be called again to do further processing.
    Eventually, OnIdle finishes processing all its idle tasks and returns 0. This tells the message loop to stop calling OnIdle until the next message is received from the message queue, at which point the idle cycle restarts with the argument set to 0.

    dokdok schrieb:

    ich sage dir meine frage nochmal.
    ich habe ein dialog mit einem knopf . wenn ich den knopf klicken startet eine schelife oder process die zählt von 1 bis 10000000 für 1000 000 mal.
    ich will daß mein dialog wärend des prossezes kann man andere knopf deucken oder das fenster verschieben.
    ich habe seit gestern rumpropiert leider kein erfolg.

    Wenn du in einer Schleife von 1 bis 1000000 zählst, wird die Nachrichtenschleife blockiert.
    Dies kannst du umgehen, wenn du z.b.

    1. einen extra Thread verwendest
    2. einen Timer verwendest
    3. OnIdle verwendest

    Nimm doch einfach einen Thread:
    Definier ne Funktion, die zählt:

    UINT CountThread( LPVOID pParam )
    {
    	for (long l=0; l<1000000; l++)
    	{
    		// tue etwas
    	}
    	return 0;
    }
    

    und ruf diese in einem anderen Thread auf, wenn man auf den Button klickt

    AfxBeginThread(CountThread, NULL);
    


  • Ich rate vom Thread ab, weil er doch sein Fenster beeinflussen will. Dann schiebt er von nem anderen Thread aus, muss aufpassen das sich nichts ins Gehege kommt usw.
    WM_TIMER benutzen und gut, wie ich schon weiter oben geschrieben habe



  • error C2665: 'AfxBeginThread': Durch keine der 2 Überladungen kann Parameter 1 vom Typ 'UINT' konvertiert werden



  • Parameter 1 ist falsch, es muss der Funktionszeiger auf die Threadfunktion sein.
    Poste mal deinen Code



  • void CProgressControlDlg::OnBnClickedButton1()
    {
       LPVOID pParam;
       AfxBeginThread(CountThread(pParam) ,NULL);
    }
    
    UINT CProgressControlDlg::CountThread( LPVOID pParam ) 
    { 
        for (long l=0; l<1000000; l++) 
        { 
            // tue etwas 
        } 
        return 0; 
    }
    


  • dokdok schrieb:

    void CProgressControlDlg::OnBnClickedButton1()
    {
    LPVOID pParam;
    AfxBeginThread(CountThread(pParam) ,NULL);
    }

    Das muss

    void CProgressControlDlg::OnBnClickedButton1()
    {
       LPVOID pParam;
       AfxBeginThread(CountThread ,NULL);
    }
    

    heißen, denn CountThread(pParam) ruft die Funktion auf und gibt den rückgabewert an AfxBeginThread weiter (was dann ein UINT ist).

    dokdok schrieb:

    UINT CProgressControlDlg::CountThread( LPVOID pParam )
    {
    for (long l=0; l<1000000; l++)
    {
    // tue etwas
    }
    return 0;
    }

    Das Funktioniert nur, wenn du CountThread in der Klasse CProgressControlDlg (mit static) statisch machst. Oder du definierst CountThread als globale Funktion.



  • ich sags doch lass die Finger von Threads :p
    😉 😉 😉

    der timer reicht hier vollkommen aus



  • oohhhhhhhhhhhhhhhhhhhhhhhhhhhhh

    es funktioniert

    ich danke euch alle.

    zitat

    ich freue mich... 🤡



  • hi pellaeon

    kannst du mir ein beispiel mit dem timer schicken.. neugirig

    wäre sehr nett.

    mit dem thread hat funktioniert dank rapha.



  • Wenn du Timer verwenden willst, mach einfach eine Behandlungsroutine für die WM_TIMER Nachricht:

    long l = 1; // unsre globale Zählervariable (besser du verwendest eine Membervariable in CProgressControlDlg
    void CProgressControlDlg::OnTimer(UINT nIDEvent) 
    {
    	l++;
    	if (l == 1000000)
    	{
    		// l ist 1000000
    		// tue was
    		KillTimer(0 /* unsere TimerID */); // Timer stoppen
    	}
    
    	CDialog::OnTimer(nIDEvent);
    }
    

    Und dann kannst du, wenn man auf den Button klickt, den Timer aufrufen

    SetTimer(0, // die id unseres Timers (frei wählbar)
             10, // mit welchen Abständen OnTimer aufgerufen werden soll (hier alle 10 Millisekunden)
             NULL // reserviert, muss immer 0 sein
    	 );
    


  • hätt ich nicht besser machen können 🤡



  • vielen dank ihr zwei



  • Pellaeon schrieb:

    ich sags doch lass die Finger von Threads :p
    😉 😉 😉

    der timer reicht hier vollkommen aus

    Sorry aber: Was für ein Quatsch.
    Dafür wurden Threads erschaffen.
    Auch wenn ein Timer ausreicht bekommt man einen Timer nur wenn Zeit ist und das auch nur ca. alle 50ms.
    Wenn aber aber diese SChleife ohne Pause abarbeiten will dann geht da nichts mit Timer.
    Und im Timer dann die SChleife aufrufen macht genausowenig SInn wie der erste Code.



  • Er sollte ja auch nicht im Timer ne Schleife machen 🙄



  • Noch eine frage,

    wie kann ich

    UpdateData(FALSE);
    

    bearbeite um ein editcontrovariable auf dem dialog zu updaten durch CountThread.
    es liefert mir
    Unzulässiger Aufruf einer nicht statischen Memberfunktion

    UINT CProgressControlDlg::CountThread2( LPVOID pParam )
    {
    
    		dokdok= i ;
    		//UpdateData(FALSE);
    
    	return 0;
    }
    


  • du brauchst einen Zeiger auf den Dialog, damit du die Methode aufrufen kannst


Anmelden zum Antworten