WorkerThreadCancellation beendet Thread nicht



  • Hallo,
    folgende Methode liest async Daten aus einem FileStream...

    void Form1::LoadFile(BackgroundWorker^ bw, DoWorkEventArgs ^ e){		
    	System::Windows::Forms::MessageBox::Show("Reading from File starts...");
    					Alltext=File::ReadAllLines(strCurrentFile); // Read whole File
    					 System::Windows::Forms::MessageBox::Show("File was read completely!");
    }
    

    Der Backgroundworker funktioniert wunderbar, jedoch beendet das CancellationEvent nur den Programmfluss (weitere Befehle werden nicht abgearbeitet), nicht aber den Thread, bei dem die Daten aus dem Stream gelesen werden -- "File was read completely!" erscheint also selbst bei Programmunterbrechung durch den User. BackgroundWorkerCompleted kommt also immer erst zum Zug, wenn Alltext gefüllt wurde und verhält sich bei Cancellation ansonsten völlig korrekt.

    Ich glaub, hier fehlt mir noch die Kenntnis von einer brachialeren Methodik, den Lese-Thread sofort zu killen oder? Ich hatte es so verstanden, dass eine Cancellation den Thread sofort beendet und nicht erst wartet, bis der aktuelle Befehl (in diesem Fall Alltext=File::ReadAllLines(strCurrentFile)) abgearbeitet wurde.



  • CancelAsync fordert das Abbrechen des anstehenden Hintergrundvorgangs an und legt die CancellationPending-Eigenschaft auf true fest.

    Über den Aufruf von CancelAsync kann die Worker-Methode ihre Ausführung anhalten und sich selbst beenden. Der Worker-Code sollte regelmäßig prüfen, ob die CancellationPending-Eigenschaft auf true festgelegt wurde.

    Wenn CancellationPending gleich true ist, wurde die CancelAsync-Methode auf dem BackgroundWorker aufgerufen.

    Diese Eigenschaft ist für die Verwendung durch den Workerthread vorgesehen, in dem regelmäßig CancellationPending geprüft und der Hintergrundvorgang abgebrochen wird, wenn der Status auf true festgelegt ist.

    Bei BackgroundWorker..::.CancellationPending findest Du in der Doku noch ein Beispiel.



  • Richtig und das entspricht auch alles meinen Code. Die Frage ist, wie ich einen Befehl(!) wie Alltext=File::ReadAllLines(strCurrentFile); abbreche, während dieser läuft. Während(!) eines einzigen Befehls kann ich das CancellationsPending nämlich nicht abfragen, nur davor oder dahinter (mit if ( worker->CancellationPending )).

    Ich kann es auch anders formulieren: Wie breche ich einen Befehl wie z.B. "Thread::Sleep(5000)" ab, während dieser läuft, bzw. zählt? Es muss doch etwas geben, das einen laufenden Befehl von aussen abschiesst? Gerade bei Streamoperationen ist dies doch sinnvoll.



  • Okay, nach weiterem Herumprobieren und erfolglosem Lesen hier und da ist meine Frage ganz einfach:

    Wie kann ich in "abgeschlossene Vorgänge", wie z.B.

    array<String^>^ Alltext=File::ReadAllLines(strCurrentFile); // Read whole File
    

    eingreifen und diese überwachen? Wie kann ich z.B. festellen, wieviele Slots des Arrays "Alltext" schon gefüllt wurden, während der Lesevorgang noch läuft? Wie kann ich solche Vorgänge vorzeitig unterbrechen oder abbrechen?



  • Richtig und das entspricht auch alles meinen Code

    Nö, in keinster weise.

    Die Frage ist, wie ich einen Befehl(!) wie Alltext=File::ReadAllLines(strCurrentFile); abbreche, während dieser läuft. Während(!) eines einzigen Befehls kann ich das CancellationsPending nämlich nicht abfragen, nur davor oder dahinter (mit if ( worker->CancellationPending ))

    Garnicht, es ist ein blockierender Aufruf. Wenn Du das nicht willst musst Du prüfen ob die "Dienstleistung" die Du verwendest Asynchronen Zugriff gewährt (der aber deswegen nicht abbrechbar ist.) , es in einen eigenen Thread packen den Du abschiessen kannst (Achtung: die Funkiton die da am machen ist kann undefiniertes verhalten bedeuten) oder Du liest die Datei in einer Schleife Zeilenweise aus und prüfst nach jeder Zeile auf das Abbruchflag.



  • Ersetze "ReadAllLines" durch "ReadLine"...


Anmelden zum Antworten