Search code examples
c#asynchronousuploadbackgroundworkerterminate

backgroundWorker exits as soon as starts, plus continues after cancel


I'm having a lot of trouble with my background worker. I have a background worker to upload pictures (sometimes over 100) to tumblr. Naturally, this is extremely repetitive.

My problems are this:
1) As soon or a few seconds after I start my thread, backgroundWorker1_RunWorkerCompleted is called, as shown by it printing the text within that method/event.
2) When I cancel the thread, it calls backgroundWorker1_RunWorkerCompleted, as shown by it printing the text within it, however, files continue to keep uploading. It seems like the thread still exists.

I can't figure out what I'm doing wrong, I've been searching for the past few days and tried so many different methods. Here is my code:

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;
        }
    }
}



And here is my 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." );
    }
}

Now, i'll try and explain what I think is happening in my DoWork,
since the for loop is what loops each photo upload, the if statement is in there so it can constantly check if cancellationpending is true. If it is, set e.Cancel to true to end the thread.
Also, I'm using ExecuteAsync to upload, so I was hoping I would be able to terminate the thread mid upload, so that photo doesn't upload.

Okay, I'm sorry, I know that this has been discussed before. I just can't figure out what I'm doing wrong though.
By the way, this is how I attempt to cancel:

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

Thank you all.


Solution

  • Two things:

    Firstly, you're trying to access the UI from the background worker:

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

    You shouldn't do that. It sounds like you should be setting up all the information the background worker needs first, then starting it.

    Secondly, the fact that you're calling ExecuteAsync is exactly why your background worker is completing immediately, but then the files are continuing to upload. You're basically queueing a load of work for the rest client to do asynchronously.

    While are you using ExecuteAsync in the first place? You're already within a background thread - why not just do the work synchronously?