2012-04-03 5 views
-2

Ist das möglich?Führen Sie BackgroundWorker in die von doWork aufgerufene Klasse?

Was ich tun möchte, ist meine DoWork-Methode instanziieren Sie eine andere Klasse und rufen Sie dann seine Startmethode. Dann möchte ich den Fortschritt von dieser Klasse zurück an den ProgressChanged-Handler in der Elternklasse melden. Ich habe versucht, einen Verweis auf den BackgroundWorker übergeben, aber ich bekomme einen Fehler.

private void ComplianceWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     ComplianceControlCenter CCC = 
     new ComplianceControlCenter(taskList.CheckedItems.OfType<string>().ToList(), 
            file_box.Text, &ComplianceWorker); 
     CCC.start(); 
    } 

EDIT:

Es gibt nur 1 Hintergrund Arbeiter. Ich möchte es mit Verweis auf den Konstruktor von ComplianceControlCenter übergeben, damit ich Fortschrittsaktualisierungen von innerhalb dieser Klasse senden kann. Die Begründung ist, dass die Klasse eine ziemlich komplizierte Arbeit macht und ich muss eine Teilung haben. Also noch einmal, würde Ich mag den Hintergrund Arbeiter aus der doWork Methode zum CCC-Objekt übergeben, so kann ich nennen ComplianceWorker.ReportProgress();

Fehler 1 nicht die Adresse nehmen, bekommen die Größe, oder einen Zeiger auf ein verwaltetes erklären type ('System.ComponentModel.BackgroundWorker')

+3

Dann die Fehlerdetails buchen. Ich denke, es hat etwas mit dem '&' in '& ComplianceWorker zu tun, aber ich würde es gerne wissen. –

Antwort

0

Sie könnten das tun, obwohl ich nicht sehe, welchen Zweck es für einfache Fälle dienen würde. Da Sie bereits innerhalb der Geschäftsmethode von BackgroundWorker sind, gibt es keinen Sinn, noch mehr Threads zu verwenden, indem Sie einen anderen BackgroundWorker erstellen, und Sie könnten die gleiche Arbeit inline tun.

Wenn Sie noch eine zweite BackgroundWorker haben möchten, können Sie Ereignisse mit geändertem Fortschritt vom zweiten zum ersten Worker propagieren, indem Sie einen Handler an das Ereignis ProgressChanged des zweiten Arbeiters anhängen. Dieser Handler würde dann das Ereignis ProgressChanged auf dem ersten Arbeiter auslösen und die Nachrichten verbreiten.

Zum Beispiel:

private void ComplianceWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var CCC = new ComplianceControlCenter(/* ... */); 

    // Assume that CCC exposes a BackgroundWorker, but read below 
    var worker = CCC.Worker; // "second" worker 
    worker.ProgressChanged += this.PropagateProgressChanged; 

    CCC.start(); 
} 

private void PropagateProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    var worker = this.worker; // "first" worker 
    worker.ReportProgress(e.ProgressPercentage, e.UserState); 
} 

Dieser Code legt eine Ereignisbehandlungsroutine der "zweiten" Arbeiter mit

var worker = CCC.Worker; // "second" worker 
worker.ProgressChanged += this.PropagateProgressChanged; 

die davon ausgeht, dass ComplianceControlCenterBackgroundWorker direkt seine eigene aussetzt. Da dies möglicherweise nicht der Fall ist, können Sie die Beziehung umkehren, indem Sie stattdessen einen Verweis auf this.PropagateProgressChanged an den Konstruktor übergeben und den Ereignishandler für Sie anhängen lassen.

+0

Ich möchte nur 1 Hintergrundarbeiter. –

0

Wenn beide Hintergrundarbeiter identisch sind, wird eine Endlosschleife ausgeführt. möglicherweise erstellen Sie zwei verschiedene Hintergrundarbeiter. Wenn Sie etwas Ähnliches zwischen ihnen benötigen, erstellen Sie eine Basisklasse/Schnittstelle.

+0

Ich denke, das OP will nur eine Referenz übergeben. –

0

Warum nicht einfach die Referenz Ihrer BackgroundWorker als Parameter an Ihre "Arbeits" -Methode übergeben?

EDIT:

In der Tat was Sie tun müssen, wenn Sie wollen Fortschritte berichten oder die CancellationPending Flagge überprüfen, ob Sie auch manuell Vorgang abbrechen möchten, können.

+0

Ja, das ist es, was ich versuche zu tun. –

+1

BackgroundWorker Worker = Absender als BackgroundWorker; – Pedro77

1

In C# Referenzen wie folgt übergeben werden:

ComplianceControlCenter CCC = new ComplianceControlCenter(..., ComplianceWorker); 

nicht diese

ComplianceControlCenter CCC = new ComplianceControlCenter(..., &ComplianceWorker); 
wie

Als Randbemerkung, ist es üblich, Variablen und Felder mit einem Kleinbuchstaben beginnen zu lassen, , so würde ich ComplianceWorker zu complianceWorker umbenennen. Beachten Sie, dass dies auch Syntax in Stackoverflow Hervorhebung verbessert: ;-)

ComplianceControlCenter ccc = new ComplianceControlCenter(..., complianceWorker); 
0

Wenn Sie die BackgroundWorker selbst innerhalb der DoWork Veranstaltung brauchen einfach die sender upCast. Vielleicht so etwas wie folgt aus:

private void ComplianceWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var worker = sender as BackgroundWorker; 
    if(worker == null) 
    { 
     //ToDo: What should happen if MS changes the behavior?? 
    } 

    ComplianceControlCenter CCC = new ComplianceControlCenter(taskList.CheckedItems.OfType<string>().ToList(), file_box.Text, worker); 
    CCC.start(); 
} 
+0

Alternativvorschlag: 'var worker = (BackgroundWorker) sender;'. Dies stellt sicher, dass das Programm mit einer InvalidCastException fehlschlägt, wenn "MS das Verhalten ändert". – Heinzi

+0

@Heinzi: Ja, du hast Recht, aber ich wollte nur auf dieses Problem im Codebeispiel hinweisen. – Oliver

0

es wurde gelöst, indem Sie diese ..

ComplianceControlCenter CCC = new ComplianceControlCenter(taskList.CheckedItems.OfType<string>().ToList(), file_box.Text,ref complianceWorker); 

Mit diesem als Konstruktor.

public ComplianceControlCenter(List<string> task_list, String exe_location, ref BackgroundWorker complianceWorker) 
Verwandte Themen