Prozess abbrechen



  • Hallo allerseits,

    Ich bin soweit eigentlich fertig mit einem Programm und mir ist aufgefallen dass es vielleicht noch nützlich wäre einen Button zum Abbrechen des Prozesses einzubauen (da es bei grösseren Datenmengen schon einige Minuten dauern kann bis der fertig ist). Eine Vorstellung des Ablaufes habe ich schon:

    Ich baue den Abbrechen-Button ganz normal ein und schreibe in die OnButtonCancel-Funktion einfach "process = 3". Diese Process-Variable ist ein globaler Int-Wert und wird beim Konstruktor des Programmes auf 1 gesetzt. Sobald ich den Button drücke um meinen Hauptprozess zu starten wird die Variable 'process' auf 2 gesetzt. Dann frage ich jedes Mal ab, ob process 3 ist (was ja nach dem klicken des Abbrechen-Buttons der Fall sein sollte) und breche die Funktion mit return; ab. Ein Problem habe ich aber: Da der PC in dieser Zeit voll am rechnen ist findet er sozusagen keine Zeit nachzuschauen ob ich den Abbrechen-Button gedrückt habe bzw. ich KANN ihn gar nicht drücken. Nun meine Frage:

    Ich weiss dass dies sicherlich mit Multithreading gehen würde aber gibt es eventuell eine andere Möglichkeit nur den Button "klickbar" zu machen? Ich steige da nämlich noch nicht ganz durch und meine ersten Multithreadingversuche sind gescheitert.

    Ich mache jetzt Wochenende und hoffe bis Montag einige Hilfestellungen dazu zu kriegen 🙂
    Danke für die Aufmerksamkeit



  • hey leutz,

    multithreading ist eigentlich relativ einfach zu machen:

    du musst nur eine globale funktion vom typ UINT mit dem parameter LPVOID
    erstellen, und dann mit AfxBeginThread erstellen:

    CWinThread* pThread;
    
    UINT WorkFunction ( LPVOID pVoid)
    {
     //HIER DEN CODE ZUM ARBEITEN EINFÜGEN
    }
    
    //ZUM BEGINNEN DES NEUEN THREADS
    pThread = AfxBeginThread ( WorkFunction, NULL /*z.b.*/);
    

    jetzt has du einen neuen thread erstellt, und einen zeiger ( pThread)
    darauf. und wenn du jetzt noch in der dokumentation nachguggst, was du damit anstellen kanns ( Stoppen, Weitermachen, Beenden usw...) hasse nen feines
    proggie, wo du dann ganz sauber zwischen workerthread und interfacethread getrennet hast!!!

    nichma so schwer, oder???

    ok, bis dann man, ich



  • Danke LUZA. Ich habs jetzt mit einer Funktion soweit hingekriegt dass alles klappt doch bei einer anderen gehts irgendwie nicht so ganz. Hier der Code:

    UINT CRouteSortDlg::ProcessSeparatingThread(LPVOID pParam)
    {
    	CRouteSortDlg* pDlg = (CRouteSortDlg*) pParam;
    
    	while(pDlg->m_Flag == 1)
    	{
    		CAdditionalFunctions	AF;
    		CRecFileFind			RFF(pDlg->m_strEditDirectoryLocation);
    
    		int				nF = 0;
    		int				FC = RFF.GetFileCount();
    		BOOL			   checkFile;
    		CString			currentFile;
    		CString			output;
    
    		for(nF = 0; nF < FC; nF++)
    		{
    			currentFile = RFF.GetFile(nF);
    
    			checkFile   = TRUE;
    			checkFile   = AF.CheckFile(currentFile);            //Eine Funktion die überprüft ob das momentane File defekt ist
    
    			if(checkFile == FALSE) //IF THE CURRENT FILE IS DAMAGED
    			{
    				output.Format("DMGD:\t%s", currentFile);
    				pDlg->m_ctlListSeparated.AddString(output, RGB(255, 0, 0));
    			}
    			else //IF THE CURRENT FILE IS NOT DAMAGED
    				pDlg->ProcessSeparating(currentFile); //Die Funktion die da aufgerufen werden soll ist vom Typ void falls das von Belang ist
    		}
    	}
    
        delete pDlg;
    
    	return 0;
    }
    

    Da hat er ein Problem genau auf der Zeile wo die Funktion ProcessSeparating() aufgerufen werden soll. Bei der anderen Funktion klappt es:

    UINT CRouteSortDlg::ProcessCopyingThread(LPVOID pParam)
    {
    	CRouteSortDlg* pDlg = (CRouteSortDlg*) pParam;
    
    	while(pDlg->m_Flag == 1)
    		pDlg->ProcessCopying(pDlg->pcOldFolder, pDlg->pcNewFolder);
    
        delete pDlg;
    
    	return 0;
    }
    

    Warum klappt die Funktionsübergabe denn da? Ist ja das selbe... 😕



  • Wie würdet es ihr denn machen wenn ihr eine bereits fertige Funktion des Typs void habt und die einfach in einem neuen Thread ausführen wollt? Dort werden Membervariablen benutzt, Klassen aufgerufen etc (halt der ganze Programmprozess)...



  • Sorry für den Triplepost aber kann mir wirklich niemand helfen? Ich würd gerne bevor ich mein hundertstes Lebensjahr erreicht habe das Programm MIT MULTITHREADING zum laufen bringen...

    Ich will nur einen neuen Thread erstellen und dann in diesem Thread auf eine bereits bestehende Funktion verweisen. Das kann doch nicht so schwer sein. Bei dem Henkesoft Tutorial wurde es so gemacht:

    [cpp]
    void CThread001Dlg::OnButtonStart()
    {
    m_Flag = 1;
    CWinThread* pThread = AfxBeginThread (thrFunction, this);
    }

    void CThread001Dlg::OnButtonStop()
    {
    m_Flag = 0;
    }

    UINT CThread001Dlg::thrFunction(LPVOID pParam)
    {
    CThread001Dlg* pDlg = (CThread001Dlg*) pParam;
    pDlg->thrRun();
    return 0;
    }

    void CThread001Dlg::thrRun()
    {
    while (m_Flag)
    {
    Sleep(1000);
    MessageBeep(0);
    }
    }[/cpp]Wie man unschwer erkennen kann ruft er IN der Thread-Funktion eine GANZ NORMALE Funktion aus dem Dialog auf. Ich wollte es ähnlich machen:

    [cpp]
    void CRouteSortDlg::OnButtonReplacing()
    {
    UpdateData(TRUE);

    ...
    CAddFunctions AF;
    CRecFileFind RFF(m_strEditDirectoryLocation, ".pt");

    int nF = 0;
    int FC = RFF.GetFileCount();
    BOOL checkFile;
    CString currentFile;
    CString output;

    GetDlgItem(IDC_BUTTON_CANCEL)->EnableWindow(TRUE);

    CreateNewDataSource();

    for(nF = 0; nF < FC; nF++)
    {
    currentFile = RFF.GetFile(nF);

    checkFile = TRUE;
    checkFile = AF.CheckFile(currentFile);

    if(checkFile == FALSE) //IF THE CURRENT FILE IS DAMAGED
    {
    output.Format("DMGD:\t%s", currentFile);
    m_ctlListSeparated.AddString(output, RGB(255, 0, 0));
    }
    else //IF THE CURRENT FILE IS NOT DAMAGED
    {
    m_Flag = 1;
    CWinThread pThread = AfxBeginThread(ProcessSeparatingThread, this);*
    }
    }

    UpdateData(FALSE);
    }

    //
    /
    /

    UINT CRouteSortDlg::ProcessSeparatingThread(LPVOID pParam)
    {
    CRouteSortDlg* pDlg = (CRouteSortDlg*) pParam;

    while(pDlg->m_Flag == 1)
    {
    pDlg->ProcessSeparating();
    }

    return 0;
    }

    //
    /
    /

    void CRouteSortDlg::ProcessSeparating()
    {
    UpdateData(TRUE);

    while(m_Flag == 1)
    {
    ... //Verdammt lange Funktion. Wenn ich die posten würde würde sich das sowieso niemand anschauen und zu verstehen versuchen
    }

    UpdateData(FALSE);
    }[/cpp]Kann mir jetzt einer erklären warum ich wenn ich den Button drücke die folgenden Fehler bekomme?

    Da muss ich etwa 15 Mal auf OK klicken damit es verschwindet
    Ein "normaler" Debug Assertion Fehler

    Ich teste schon den ganzen Tag rum und habe schon die grosse Funktion komplett umgeschrieben aber sobald ich eine Member-Variable "beschreiben" will geht er wieder zum while(m_Flag == 1) ganz oben zurück. Bringt mir nicht besonders viel.


Anmelden zum Antworten