2012-03-24 7 views
1

Ich habe eine Menge Probleme mit meinem Hintergrundarbeiter. Ich habe einen Hintergrundarbeiter, um Bilder (manchmal über 100) nach Tumblr hochzuladen. Natürlich ist das extrem repetitiv.

Meine Probleme sind dies:
1) Sobald oder ein paar Sekunden, nachdem ich meinen Thread starten, backgroundWorker1_RunWorkerCompleted genannt wird, wie durch den Druck, den Text innerhalb dieser Methode/Veranstaltung gezeigt.
2) Wenn ich den Thread abbricht, ruft er backgroundWorker1_RunWorkerCompleted auf, wie es durch das Drucken des darin enthaltenen Textes angezeigt wird, Dateien werden jedoch weiterhin hoch geladen. Es scheint, als ob der Thread noch existiert.

Ich kann nicht herausfinden, was ich falsch mache, ich habe in den letzten paar Tagen gesucht und so viele verschiedene Methoden ausprobiert. Hier ist mein Code:
backgroundWorker beendet, sobald beginnt, plus fährt nach Abbrechen fort

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker backgroundWorker = sender as BackgroundWorker; 
    var restClient = new RestClient("http://tumblr.com/api/write"); 
    foreach (string item in queueBox.Items) 
    { 
     if (!backgroundWorker.CancellationPending) 
     { 
      var request = new RestRequest(Method.POST); 
      request.RequestFormat = DataFormat.Json; 
      request.AddParameter("email", usernameBox.Text); 
      request.AddParameter("password", passwordBox.Text); 
      request.AddParameter("type", "photo"); 
      byte[] byteArray = File.ReadAllBytes(FolderName + "\\" + item); 
      request.AddFile("data", byteArray, FolderName + "\\" + item); 
      var newItemToAvoidClosure = item; 
      restClient.ExecuteAsync(request, response => { doneBox.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { newItemToAvoidClosure }); }); 
     } 
     else 
     { 
      e.Cancel = true; 
     } 
    } 
} 



Und hier ist mein RunWorkerCompleted

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (!(e.Cancelled)) 
    { //if not cancelled 
     if (!(e.Error == null)) 
     { //if above true, see if theres an error 

      doneBox.Items.Add("\r\nAn Error Ocurred: " + e.Error.Message + "\r\n. However, what you uploaded may have been successful up until this error."); 
     } 
     else 
     { //else there is no error which means it was 100% successful 
      doneBox.Items.Add("Finished uploading! Go and check out your stuff on Tumblr! ^_^"); 
     } 
    } 
    else //else the user DID press cancel 
    { 
     doneBox.Items.Add("You pressed Cancel - However, the photos before you pressed cancel have been uploaded."); 
    } 
} 

Nun, ich werde es versuchen und erklären, was ich denke, geschieht in meinem DoWork,
da die für Schleife ist, was jedes Foto-Upload-Schleifen, die if-Anweisung ist da drin, so dass es ständig überprüfen kann, ob die Aufhebung der Zahlung wahr ist. Wenn dies der Fall ist, setzen Sie e.Cancel auf "true", um den Thread zu beenden.
Außerdem verwende ich ExecuteAsync zum Hochladen, also hoffte ich, dass ich in der Lage wäre, den Thread mitten im Upload zu beenden, damit das Foto nicht hochgeladen wird.

Okay, tut mir leid, ich weiß, dass dies bereits besprochen wurde. Ich kann einfach nicht herausfinden, was ich falsch mache.
By the way, das ist, wie ich abzubrechen versuchen:

public void stopButton_Click(object sender, EventArgs e) 
{ 
    doneBox.Items.Add("You pressed the stop button."); 
     backgroundWorker1.CancelAsync(); 
} 

Vielen Dank.

+1

Solange Sie ExecuteAsync() verwenden, haben Sie keine Verwendung für einen BackgroundWorker. Verwenden Sie stattdessen Execute(), so dass Sie tatsächlich abbrechen können. –

Antwort

3

Zwei Dinge:

Zum einen versucht man die Benutzeroberfläche aus dem Hintergrund Arbeiter zuzugreifen:

request.AddParameter("email", usernameBox.Text); 

Sie das nicht tun sollte. Es hört sich so an, als sollten Sie alle Informationen einrichten, die der Hintergrundarbeiter benötigt, zuerst und dann.

Zweitens, die Tatsache, dass Sie ExecuteAsync aufrufen, ist genau, warum Ihr Hintergrundarbeiter sofort fertig ist, aber dann werden die Dateien weiterhin hochgeladen. Sie stellen im Grunde eine Arbeitslast für den Rest-Client bereit, um asynchron zu arbeiten.

Während Sie ExecuteAsync in erster Linie verwenden? Sie befinden sich bereits in einem Hintergrund-Thread - warum nicht einfach synchron arbeiten?

+0

Nun, meines Wissens würde 'Execute' blockieren und ich wäre nicht in der Lage, das Hochladen von MID UPLOAD zu beenden. Du sagst also, dass dies einfach mit 'Execute' möglich ist? – Anteara

+0

+1 Genau die Antworten, die ich im Sinn hatte – GETah

+0

@Anteara: Sie werden wahrscheinlich nicht in der Lage sein, es Mitte-Upload zu beenden, aber die Art, wie Sie es gerade tun, versucht, * alle * die Uploads im Grunde zu starten Gleichzeitig, und du hast sowieso keine Möglichkeit, es aufzuheben. Zumindest wenn Sie jede Anfrage synchron ausführen, können Sie zum richtigen Zeitpunkt anhalten. Ich kenne 'RestClient' nicht gut genug, um seine Abbruchstrategie zu kennen, aber ich würde sagen, dass "synchron im Hintergrund" zumindest besser wäre als Ihr aktueller Ansatz. –