Здесь есть несколько потенциальных проблем.
Во-первых, вы, кажется, пытаетесь получить доступ к элементу пользовательского интерфейса из фонового потока (а также открыть MessageBox). Это может привести к возникновению исключения CrossThread *.
Во-вторых, ваш код должен выглядеть примерно так:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var restClient = new RestClient("http://tumblr.com/api/write");
foreach (string item in queueBox.Items)
{
//This should be inside the foreach
//as it is your loop that will check for cancel.
//Your code is procedural once it is in the backgroundworker
//so it would never return to the spot you had it
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
//MessageBox.Show("You pressed Cancel.");
//Removed this to the background worker completed method below
//This avoids any UI cross thread exceptions
return;
}
var request = new RestRequest(Method.POST);
//I believe Json is default for Restsharp, but you would have to play with it
request.RequestFormat = DataFormat.Json; //I don't know if this line is necessary
request.AddParameter("email", usernameBox.Text);
request.AddParameter("password", passwordBox.Text);
request.AddParameter("type", "photo");
request.AddFile("data", FolderName + "\\" + item);
//If you just pass in item to the below Func, it will be a closure
//Meaning, any updates in the loop will propogate into the Action
var newItemToAvoidClosure = item;
//To use Async, you set up the callback method via a delegate
//An anonymous method is as good as any here
restClient.ExecuteAsync(request,
response=>
{
//Maybe you should do something with the response?
//Check the status code maybe?
doneBox.Invoke(new UpdateTextCallback(this.UpdateText),
new object[] { newItemToAvoidClosure });
}
);
}
}
Подключите метод RunWorkerCompleted
вашего фонового работника к этому и выполните всю вашу пост-обработку здесь:
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
if(e.Cancelled)
MessageBox.Show("You pressed Cancel"
}
Кроме того, если вы используете 4.0+, то я предлагаю заглянуть в Task Parallel Library . Это может сделать ваш код намного чище IMO :).
Наконец, примечание о приведенном выше коде, что произойдет, это то, что фоновый работник имеет высокий потенциал для возврата завершено до завершения всех вызовов Rest. Это, вероятно, будет выполняться довольно быстро, и вызовы будут продолжаться, поскольку они не могут быть отменены таким образом (фоновый рабочий уже завершил) (но я полагаю, что есть способ сделать это для каждого вызова Rest). Таким образом, мне кажется, что реальная проблема заключалась в том, что проверка отмены была в неправильной части кода (обратите внимание, что я переместил его в цикл, чтобы его можно было проверить после обработки каждого файла). Вы уже работаете в фоновом потоке, поэтому мне кажется, что нет смысла вызывать другой асинхронный режим (если только вы не намерены разгрузить цикл данных, подлежащих отправке, что затем разгрузит фактическую отправку).
Итак, в заключение. Я предоставил способ вызвать асинхронный вызов, но я считаю, что большая проблема заключалась в том, что вы не проверяли вызов отмены надлежащим образом.
* Это может быть не так, поскольку вы только получаете доступ и не обновляете элемент пользовательского интерфейса, и вы сказали, что эта часть работает (хотя, вероятно, это будет работать с MessageBox)