Abbrechen des Backgroundworkers funktioniert nicht wie erfolgt

18/02/2008 - 20:03 von Jan Baer | Report spam
Hallo alle zusammen,

ich habe eine WPF Anwendung, bei der ich im Hintergrund über den
Backgroundworker Daten laden, wàhrend der Benutzer im Vordergrund an der
Oberflàche schon irgendwelche Eingaben vornehmen kann. Es kann also sein,
das der Benutzer durch eine bestimmte Aktion andere Daten laden will, als
die, die der Backgroundworker gerade làdt.

In der Methode, die das Laden über den Backgroundworker initiert, prüfe ich
mit backgroundWorker.IsBusy, ob der Backgroundworker gerade beschàftigt ist.
Wenn ich dort True zurück bekomme, dann breche ich mit
backgroundWorker.CancelAsync den Ladevorgang ab.

if(backgroundWorker.IsBusy)
{
backgroundWorker.CancelAsync();

while(backgroundWorker.IsBusy)
{
Thread.Sleep(100);
}
}

backgroundWorker.RunWorkerAsync();

Im DoWork-Ereignis frage ich CancellationPending ab und setze dann
eventArgs.Cancel = true.

Im RunWorkerCompleted Ereignis sollte dann eigentlich Cancelled = true sein.

Soweit die Theorie, in der Praxis bleibt der Code in der while-Schleife
hàngen. Selbst wenn ich nur einmal den aktuellen Thread (über habe es bis
1000ms versucht) schlafen schicke, damit der Hintergrundthread Zeit bekommt,
abzubrechen, funktioniert das ganze nicht. Obwohl im DoWork-Ereignis
eventArgs.Cancel auf true gesetzt wird, ist im Eventhandler von
RunWorkerCompleted die Eigenschaft Cancelled = false. Nach Thread.Sleep ist
der backgroundWorker auch immer noch IsBusy = true.

Weiß jemand, wo hier der Fehler vergraben ist? Wenn ich Thread.Sleep
aufrufe, dann schicke ich doch den aktullen Thread, also in dem Falle den
Vordergrundthread schlafen. Der Hintergrundhtread sollte doch dadurch
eigentlich die Zeit bekommen, um ordnungsgemàß abzubrechen oder?

Vielen Dank für Eure Hilfe im voraus!

Beste Grüße

Jan
 

Lesen sie die antworten

#1 Frank Dzaebel
18/02/2008 - 21:16 | Warnen spam
Hallo Jan,

In der Methode, die das Laden über den Backgroundworker initiert, prüfe
ich mit backgroundWorker.IsBusy, ob der Backgroundworker gerade
beschàftigt ist.
Wenn ich dort True zurück bekomme, dann breche ich mit
backgroundWorker.CancelAsync den Ladevorgang ab.



ist denn WorkerSupportsCancellation auf true?

_____________
Hier ein Beispiel:

using System;
using System.Threading;
using System.ComponentModel;

class Program
{
static BackgroundWorker bw;
static void Main()
{
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;

bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;

bw.RunWorkerAsync ("Hello to worker");

Console.WriteLine ("Press Enter in the next 5 seconds to cancel");
Console.ReadLine();
if (bw.IsBusy) bw.CancelAsync();
Console.ReadLine();
}

static void bw_DoWork (object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i += 20)
{
if (bw.CancellationPending)
{
e.Cancel = true; return;
}
bw.ReportProgress (i);
Thread.Sleep (1000);
}
e.Result = 123; // This gets passed to RunWorkerCompleted
}

static void bw_RunWorkerCompleted (object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
Console.WriteLine ("You cancelled!");
else if (e.Error != null)
Console.WriteLine ("Worker exception: " + e.Error.ToString());
else
Console.WriteLine ("Complete - " + e.Result); // from DoWork
}

static void bw_ProgressChanged (object sender,
ProgressChangedEventArgs e)
{
Console.WriteLine ("Reached " + e.ProgressPercentage + "%");
}
}

[Threading in C# - Part 3 - Using Threads]
http://www.albahari.com/threading/part3.html


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen