einfaches thread
-
ich habe das timerbeispiel einmal geschaut
mmm ich denke drin war was ich suche. die aktuellezeit hat erschien während ich mit dem dialog was anders tue..ich denke ich muß zurück zu dem timer beispiel.
die funktion OnIdle ist mir komplitziert..kann sein weil in sams in verbindung mit zeichnen und farben kam..
kannst du siese funktion OnIdle in meinem beispiel einsetzen...wenn ja wäre ich dankbar....
-
In der MSDN findest du was:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_cwinapp.3a3a.onidle.aspDieses Bsp ist denke ich einleuchtend (Quelle: msdn)
// In this example, four idle loop tasks are given various // opportunities to run: // Task1 is always given a chance to run during idle time, provided // that no message has queued up while the framework was processing // its own idle loop tasks (at lCount levels 0 and 1). // Task2 is given a chance to run only if Task1 has already run, // provided that no message has queued up while Task1 was running. // Task3 and Task4 are given a chance to run only if both Task1 and // Task2 have already run, and no message has queued up in the mean // time. If Task3 gets its chance to run, then Task4 always gets // a chance to run immediately after Task3. BOOL CMyApp::OnIdle(LONG lCount) { // In this example, as in most applications, you should let the // base class CWinApp::OnIdle complete its processing before you // attempt any additional idle loop processing. if (CWinApp::OnIdle(lCount)) return TRUE; // The base class CWinApp::OnIdle reserves the lCount values 0 // and 1 for the framework's own idle processing. If you wish to // share idle processing time at a peer level with the framework, // then replace the above if-statement with a straight call to // CWinApp::OnIdle; and then add a case statement for lCount value // 0 and/or 1. Study the base class implementation first to // understand how your idle loop tasks will compete with the // framework's idle loop processing. switch (lCount) { case 2: Task1(); return TRUE; // next time give Task2 a chance case 3: Task2(); return TRUE; // next time give Task3 and Task4 a chance case 4: Task3(); Task4(); return FALSE; // cycle through the idle loop tasks again } return FALSE; }
Grüße Raphael
-
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.- einen extra Thread verwendest
- einen Timer verwendest
- 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