4 Stimmen

Ausführen der Klasse als neuer Thread

Ich möchte einen Auftrag in einem neuen Thread starten oder den Backgroundworker dafür verwenden, habe das aber noch nie gemacht und frage euch, wie ich es machen soll.

Mein Programm hat eine Datentabellenansicht mit einer Liste von Dateien, eine Datei pro Zeile. Ich möchte, dass der Benutzer eine Zeile auswählen und dann auf "Download starten" klicken kann, um den Download im Hintergrund zu starten. Ich möchte Ereignisse über den Fortschritt des Downloads zurückerhalten.

Ich habe eine Klasse clsDownload, die alles behandelt und Ereignisse zurück wirft, aber wie implementiere ich die Hintergrundarbeit?

Sollte ich die System.ComponentModel.BackgroundWorker innerhalb der Klasse verwenden oder erstellen Sie einige Wrapper, die dies behandelt oder einige andere Threading Zeug verwenden?

Gracias.

Editar: Ich verstehe nicht, wie ich meinen Download im Backgroundworker implementieren kann, ein kleines Beispiel wäre sehr nett. Das Beispiel auf msdn hat mich nicht weit gebracht.

Ich habe eine Download-Klasse, die eine StartDownload-Funktion hat. Sollte ich den Backgroundworker IN der Klasse oder im Aufrufer verwenden? "Ich fühle mich dumm"

4voto

Inferis Punkte 4442

Ich würde dringend raten BackgroundWorker wenn Sie dem Benutzer Feedback zur Benutzeroberfläche geben müssen. Die ProgressChanged y RunWorkerCompleted Ereignisse werden auf dem UI-Thread ausgeführt, so dass kein Marshalling erforderlich ist, das Ihren Code komplexer machen kann.

3voto

Franci Penov Punkte 73239

Wenn Sie nur das Herunterladen durchführen wollen und keine andere asynchrone Verarbeitung benötigen, können Sie einfach die asynchronen Methoden der WebClient Klasse. Da Sie aber bereits Ihre eigene Klasse haben, ist das wahrscheinlich keine Lösung für Sie.

Andernfalls können Sie BackgroundWorker wie Sie erwähnt haben. Auf der MSDN-Seite finden Sie ein Beispiel, wie das geht.

EDIT: Die kurze Geschichte ist:

  • Sie erstellen die BackgroundWorker vom Anrufer;
  • Wenn Sie die Hintergrundarbeit starten wollen, rufen Sie BackgroundWorker.RunWorkerAsync ;
  • im DoWork Event-Handler erledigen Sie die Hintergrundarbeit, in Ihrem Fall starten Sie Ihre Download-Klasse;
  • Während Sie im Hintergrund arbeiten, müssen Sie ab und zu überprüfen, ob CancelationPending ;
  • Wenn Sie einen Fortschritt melden wollen, müssen Sie ihn in Prozent berechnen und die ReportProgress .

Und wenn Sie etwas wirklich Individuelles brauchen, können Sie jederzeit Ihre eigene Thread .

Ich persönlich würde mich an BackgroundWorker . Es enthält eine Reihe von Benachrichtigungen für verschiedene Phasen der Arbeit. Wenn Sie Thread müssen Sie diese selbst umsetzen.

Ich würde auch darauf achten, dass der Code nicht zu viele Instanzen erzeugt. Sie möchten die Anzahl der gleichzeitigen Downloads begrenzen und alles, was über diese Anzahl hinausgeht, in eine Warteschlange stellen.

1voto

Chris Tybur Punkte 1545

Ich habe mehrere verschiedene Klassen erstellt, die BackgroundWorker einbeziehen. In der Regel habe ich eine BackgroundWorker-Komponente auf dem Formular, das geöffnet wird, wenn der Auftrag ausgeführt wird, und übergebe diese Instanz dann an den Konstruktor meiner Auftragsklasse.

So könnte Ihre Berufsgruppe aussehen:

Private m_bwMain As BackgroundWorker

Public Sub New(ByVal bwMain As BackgroundWorker)
    m_bwMain = bwMain

    'additional setup code here
End Sub

Um einen Auftrag zu starten, würden Sie im Click-Ereignishandler der Schaltfläche Download starten etwa so vorgehen:

lblStatus.Text = "Initializing ..."
bgwMain.RunWorkerAsync(someFileName)

Ich deklariere meine Jobklasse als privates Mitglied des aktuellen Formulars und instanziiere sie dann im BackgroundWorker.DoWork-Ereignis. Von dort aus können Sie Ihre Methode zum Herunterladen einer Datei aufrufen:

Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork
    m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker))
    m_oJobEngine.DownloadFile(CStr(e.Argument))
End Sub

Um dem Benutzer den Fortschritt zu melden, können Sie die von Ihrer Klasse ausgelösten Ereignisse in Ihrem Hauptformular behandeln. Sie müssen nur sicherstellen, dass die Objektdeklaration der Jobklasse das Schlüsselwort WithEvents enthält. Von diesen Handlern aus können Sie die Methode ReportProgress von BackgroundWorker aufrufen. Innerhalb von ReportProgress können Sie beliebige Änderungen an der Benutzeroberfläche vornehmen, um den Fortschritt anzuzeigen. Hier ist ein Beispiel:

Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress
    bgw.ReportProgress(0, bytesTransferred)
End Sub
Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged
    lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred."
End Sub

Ich hoffe, das hilft.

0voto

Ian Punkte 32230

Der Backgroundworker sieht aus, als sollte er funktionieren... Es gibt ein Beispiel auf MSDN.

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Oder Sie könnten etwas tun wie:

WaitCallBack workCallBack= new WaitCallBack(DownloadMethod);
if(!ThreadPool.QueueUserWorkItem(workCallBack, "ThreadPooled")
{
   // Unable to Pool
}

// Work has been added to pool and will execute when possible

Das hängt davon ab, welche Parameter Sie für den Thread benötigen.

0voto

mbeckish Punkte 10318

Die Klasse, die clsDownload verwendet (wahrscheinlich Ihre Formularklasse), sollte BackgroundWorker verwenden, um die Download-Methode auszuführen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X