2016-05-20 15 views
0

Ich weiß, dass diese Frage mehrmals gepostet hat, aber diese Situation ist anders. Vorausgesetzt, dass ich eine Methode ausführe, die mehrere Elemente durchlaufen muss (Datenbankzeilen), benötigt dies viel Zeit.
Jetzt in meinem BackgroundWorker muss ich in einigen Fällen die Synchronisation stoppen, insbesondere wenn der Benutzer eine Taste drückt. Was ich tat, im _DoWork Ereignis ist dies:Kann den BackgroundWorker nicht stoppen

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while (!worker.CancellationPending) 
    { 
     LongOperation(); 
    } 
} 

jetzt ist das Problem, dass wenn ich worker.CancelAsync() nennen die LongOperation() die Ausführung fortsetzen sollte aber nicht! Denn die while haben den Zustand CancellationPending. Ich sah im Netz, dass diese Lösung thread-safe ist, also mache ich vielleicht etwas falsch?

+0

Was meinst du? Erwarten Sie, dass LongOperation() in der Mitte seiner Ausführung unterbrochen wird? –

+0

@AdrianoRepetti Genau, ich muss es mitten in der Ausführung stoppen – IlDrugo

+0

Sie müssten in LongOperation gehen und alle Loops, die Sie dort haben, verlassen. – LarsTech

Antwort

4

Alles, was Sie brauchen, ist die folgende Struktur

private void runButton_Click(object sender, EventArgs e) 
{ 
    worker=new BackgroundWorker(); 

    worker.WorkerSupportsCancellation=true; 
    worker.RunWorkerCompleted+=Bk_RunWorkerCompleted; 
    worker.DoWork+=Bk_DoWork; 
    worker.RunWorkerAsync(); 
} 

private void cancelButton_Click(object sender, EventArgs e) 
{ 
    worker.CancelAsync(); 
} 

void ReallyReallyLongOperation(BackgroundWorker worker) 
{ 
    ...within a loop 
    if(worker.CancellationPending) 
    { 
     return; 
    } 
} 

private void Bk_DoWork(object sender, DoWorkEventArgs e) 
{ 
    ReallyReallyLongOperation(worker); 
    if(worker.CancellationPending) 
    { 
     e.Cancel = true; 
    } 
} 

private void Bk_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if(!e.Cancelled) 
    { 
     ... 
    } 
} 
1

die LongOperation() die Ausführung fortsetzen sollte aber nicht! Denn die while haben den Zustand CancellationPending.

Nein, es sollte die Ausführung fortsetzen! Sie sind völlig falsch mit dem Verständnis der while Prüfung. Es prüft nicht jede Sekunde auf die Stornierung, es erfolgt die Überprüfung erst vor dem Start der LongOperation!

Das einzige, was man in einer solchen Situation tun können, ist die worker.CancellationPending Eigenschaft innerhalb die LongOperation Methode zu überprüfen, nicht außerhalb.