[C#] Backgroundworker beendet nicht

DexXxtrin

Erfahrenes Mitglied
Hallo zusammen

Ich habe ein Problem mit dem Backgroundworker. Und zwar rufe ich eine
Endlosschlaufe, welche immer überprüft ob abgebrochen wurde, auf. Nun
kann ich diese aber nicht mehr beenden.

Gruss DexXxtrin

C#:
private void main()
        {
            ...
            bw.RunWorkerAsync();
            if (MessageBox.Show("writing data finished!\r\npress ok to continue...") == DialogResult.OK)
            {
                bw.CancellationPending=true
            }
            ...
        }

private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            PBSendData(0xF0);
            PBSendData(0x00);
            PBSendData(0x00);
            for (int j = 0; j < 3; j++)
            {
                readData();
            }
            for ( int i = 0; i < 1; i = 0)
            {
                PBSendData(0xFF);
                readData();
                if (bw.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
            }
            
        }
 
Hallo DexXxtrin,

eigentlich dürfte der Aufruf

C#:
...
bw.CancellationPending=true
...
gar nicht funktionieren, da CancellationPending eine schrebgeschützte Property ist. An dieser Stelle sollte eigentlich eine Exception kommen.

Versuch mal folgendes:

C#:
private void main()
        {
            ...
            bw.RunWorkerAsync();
            if (MessageBox.Show("writing data finished!\r\npress ok to continue...") == DialogResult.OK)
            {
                bw.CancelAsync();            }
            ...
        }


Gruss Steffen
 

DexXxtrin

Erfahrenes Mitglied
Ou sry. Das ist mein Fehler. Hatte es so (bw.CancelAsync()). Aber es hat nicht funktioniert...

C#:
private void main()
        {
            ...
            bw.RunWorkerAsync();
            if (MessageBox.Show("writing data finished!\r\npress ok to continue...") == DialogResult.OK)
            {
                bw.CancelAsync();
            }
            ...
        }
 
private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            PBSendData(0xF0);
            PBSendData(0x00);
            PBSendData(0x00);
            for (int j = 0; j < 3; j++)
            {
                readData();
            }

            while (!bw.CancellationPending)
            {
                PBSendData(0xFF);
                readData();
            }
            e.Cancel = bw.CancellationPending;
           
        }
 
Zuletzt bearbeitet:
Dann kann es nur daran liegen, dass er nicht duch die while-Schleife kommt, z.B weil der write- oder der Read-Befehl hängt und auf die Gegenseite wartet. (Vielleicht hängt er auch schon in der for-Schleife bei write() oder read()?)


Gruss Steffen
 

DexXxtrin

Erfahrenes Mitglied
Nein er kommt in die while-Schlaufe und er hängt auch nicht dort drin. Das würde ich auf der Hardware sehen. Er läuft diese Befehle ordnungsgemäss durch.

**Edit**
--------------------
Er verlässt auch die while-Schlaufe. Aber beim nächsten durchlauf um den Backgroundworker zu starten, meldet er, dass er noch beschäftigt sei.
 
Zuletzt bearbeitet:

MCoder

Erfahrenes Mitglied
Hallo,

ich verstehe nicht, was die MessageBox direkt nach dem Start des BackgroundWorkers dort verloren hat. Sie sollte lieber im Handler des RunWorkerCompleted-Events stehen. Wenn bw_DoWork sauber bis zum Ende durchläuft, gibt es eigentlich auch keinen Grund, den DoWorkEventArgs-Member "Cancel" zu ändern.

Gruß
MCoder
 
Mit dem setzten des DoWorkEventArgs-Members Cancel auf 'true' wird bewirkt, dass der Abbruch abgebrochen wird.

Hab das grad hier mal probiert. So klappts:
C#:
		static void Main(string[] args)
		{
			BackgroundWorker bw = new BackgroundWorker();
			bw.WorkerSupportsCancellation = true;
			bw.DoWork += new DoWorkEventHandler(bw_DoWork);

			bw.RunWorkerAsync();
			if (MessageBox.Show("writing data finished!\r\npress ok to continue...") == DialogResult.OK)
			{
				bw.CancelAsync();
			}
			while (bw.IsBusy)
				Thread.Sleep(10);
		}

		static void bw_DoWork(object sender, DoWorkEventArgs e)
		{
			BackgroundWorker worker = sender as BackgroundWorker;
			while (!worker.CancellationPending)
			{
				Console.WriteLine("Ich Arbeite");
				Thread.Sleep(500);
			}
			//e.Cancel = true;
			Console.WriteLine("Fertig");
		}

Im übrigen sollte man im Evemthandler nie direkt auf den Backroundworker zugreifen, sondern den als 'sender' mitgegebenen verwenden.
 

DexXxtrin

Erfahrenes Mitglied
@SteffenBoerner:
So hat es bei mir auch nicht funktioniert. Ich habe jetzt aber selbst eine Lösung gefunden. Ich muste noch ein Application.DoEvents() einfügen. Nun beendet der Backgroundworker ;)
 
3

316037

@DexXtrin: Es wäre ganz informativ, an welcher Stelle genau der Aufruf von DoEvents in deinem Code erfolgen musste, damit es funktioniert hat......
 

DexXxtrin

Erfahrenes Mitglied
So:

C#:
private void main()
        {
            ...
            bw.RunWorkerAsync();
            if (MessageBox.Show("writing data finished!\r\npress ok to continue...") == DialogResult.OK)
            {
                bw.CancelAsync();
                Application.DoEvetns();
            }
            ...
        }
 
private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            PBSendData(0xF0);
            PBSendData(0x00);
            PBSendData(0x00);
            for (int j = 0; j < 3; j++)
            {
                readData();
            }

            while (!bw.CancellationPending)
            {
                PBSendData(0xFF);
                readData();
            }
            e.Cancel = bw.CancellationPending;
           
        }