Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Multithreading will nicht

Empfohlene Antworten

Veröffentlicht

Hallo allerseits,

Gestern habe ich den ganzen Tag damit verbracht mein schon fertiges Programm mit Multithreading zum laufen zu bringen weil ich einen Button einfügen wollte der zum abbrechen des Prozesses dient. Ich habe es immernoch nicht geschafft und bin nahe der Erschöpfung :D

Bei dem Henkesoft Tutorial wurde es so gemacht:

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);

  }

}
Wie man unschwer erkennen kann ruft er in der Thread-Funktion eine ganz normale Funktion der Klasse aus dem Dialog auf. Ich wollte es ähnlich machen:
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++)

    {

        ...

        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 vermutlich niemand anschauen und sie ist nicht von Belang

    }


    UpdateData(FALSE);

}

Könnte mir jetzt vielleicht jemand sagen 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

An den Funktionen selber liegt es nicht denn die funktionieren ohne Multithreading tadellos, ich muss nur noch das obige hier zum laufen kriegen :)

Vielen Dank im Voraus

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++)

    {

        ...

        else //IF THE CURRENT FILE IS NOT DAMAGED

        {

            m_Flag = 1;

[COLOR=SandyBrown]// bei jedem Durchlauf ein neuer Thread ???[/COLOR]            

CWinThread* pThread = AfxBeginThread(ProcessSeparatingThread, this);

        }

    }


    UpdateData(FALSE);    

}


/**************************************************************************************************************************/

/**************************************************************************************************************************/


UINT CRouteSortDlg::ProcessSeparatingThread(LPVOID pParam)

{

    CRouteSortDlg* pDlg = (CRouteSortDlg*) pParam;


[COLOR=SandyBrown]// Wozu diese Schleife ? Ist doch schon im Thread sowas-> unnötig [/COLOR]    

while(pDlg->m_Flag == 1)

    {

        pDlg->ProcessSeparating();

    }


    return 0;

}


/**************************************************************************************************************************/

/**************************************************************************************************************************/


void CRouteSortDlg::ProcessSeparating()

{

    UpdateData(TRUE);


[COLOR=SandyBrown]// Soll das Programm unendlich lange ausgeführt werden ? Wenn nicht brauchst du gar keine Schleife hier, da die Funktion dann nur 1 Mal durchlaufen wird (im seperaten Thread natürlich)[/COLOR]


 while(m_Flag == 1) 

    {

        ... //Verdammt lange Funktion. Wenn ich die posten würde würde sich das vermutlich niemand anschauen und sie ist nicht von Belang

    }


    UpdateData(FALSE);

}

Könnte mir jetzt vielleicht jemand sagen warum ich wenn ich den Button drücke die folgenden Fehler bekomme?

Am besten sagst du nochmal, wie oft die Thread Funktion durchlaufen werden soll, oder so.

Hi dieterds,

Ich bearbeite Files. Und mithilfe der Klasse CRecFileFind kann ich in einer for-Schleife File für File "holen" und dieses dann einer Klasse weitergeben und weiterverarbeiten. Aus diesem Grund sollte ich den Thread jedes Mal neu aufrufen, das aktuelle File durchscannen lassen und dann wieder schliessen. Das ist aber nicht die Problematik. Es geht eher darum, dass ich in der Methode die ich aufrufe danach keinen Zugriff auf Membervariablen habe. Sobald er entweder auf eine Zeile trifft wo ich etwas in ein Control schreiben will oder wenn er auf eine normale Funktion die ich aufrufen will trifft springt er einfach wieder zur ersten Zeile des Threads zurück. Beispiel:

Ich habe folgende Funktionen (alle in der selben Klasse):

- OnButtonIrgenwas()

- ProcessFile()

- GetDatabaseInformation()

- GetRouteInformation()

So, dann will ich aus dem OnButtonIrgendwas() die Funktion ProcessFile() in einem neuen Thread aufrufen. In DIESER Funktion (ProcessFile) benutze ich aber noch andere Funktionen damit mein Vorgang durchgeführt werden kann. Und zwar GetDatabaseInformation() und GetRouteInformation. Nun, das weiterleiten von OnButtonIrgendwas() zu ProcessFile() in einem neuen Thread funktioniert. Sobald ich jedoch im neuen Thread eine der zwei "Hilfsmethoden" aufrufen will springt er mir sofort zu der ersten Zeile von ProcessFile() zurück. Und auch wenn ich eine Editbox (egal ob sie Control, String oder was auch immer ist) beschreiben will, springt er auch sofort zu der ersten Zeile von ProcessFile() zurück. Ist das soweit verständlich oder hab ich etwas komisch erklärt?

Umgehen kann ich das alles nicht. Die Hilfsmethoden brauche ich umbedingt, beschreiben muss ich die Membervariablen meines Dialoges ebenfalls. Der Prozess kann halt einige Minuten dauern und wenn einfach nichts geschieht denkt der User das Programm sei abgekratzt, also muss ich ihm zeigen welche Files momentan bearbeitet werden etc.

Danke für die Aufmerksamkeit

Hm.... würde die ganze Thread Bearbeitung in eine eigene Klasse machen,

aber wir probieren das mal einfach so..

Eine ganz andere Methode wäre natürlich, die gesamte Dateiverarbeitung in einem Thread ablaufen zu lassen, dann müsste nicht für jede Datei ein eigener Thread eröffnet werden und es würde der Dateioperation zu Gute kommen.


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();


	// Durchlaufen der Dateien

	for(nF = 0; nF < FC; nF++)

	{

		...

		else //IF THE CURRENT FILE IS NOT DAMAGED

		{

			// Für jede heile Datei 1 neuer Thread zur Verarbeitung          

			AfxBeginThread(ProcessSeparatingThread, this);

		}

	}


	UpdateData(FALSE);    

}


/**************************************************  **************************************************  **********************/

/**************************************************  **************************************************  **********************/


UINT CRouteSortDlg::ProcessSeparatingThread(LPVOID pParam)

{

	// Neuer Dialog wird erzeugt

	CRouteSortDlg* pDlg = (CRouteSortDlg*) pParam;


	//Thread-Befehle werden abgearbeitet

	pDlg->ProcessSeparating();

	return 0;

}


/**************************************************  **************************************************  **********************/

/**************************************************  **************************************************  **********************/


void CRouteSortDlg::ProcessSeparating()

{

	UpdateData(TRUE);


	//////////////////////////////////////////////////////////////////////////

	// Hier kommen die Sachen rein, die mit der Datei gemacht werden sollen //

	//////////////////////////////////////////////////////////////////////////


	UpdateData(FALSE);

}

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.