>>>>>>>>>Thanks Viv,
>>>>>>>>>I think I have it working now.
>>>>>>>>
>>>>>>>>Just for the heck of it - a Task based version which gets rid of BackgroundWorker altogether and, because it's parallel, should be a whole lot faster:
private void BtnTask_OnClick(object sender, RoutedEventArgs e)
>>>>>>>> {
>>>>>>>> btnTask.IsEnabled = btnEmail.IsEnabled = false;
>>>>>>>> txtInfo.Text = string.Empty;
>>>>>>>>
>>>>>>>> //Dummy list of Primary Keys
>>>>>>>> var emailPKs = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
>>>>>>>> progressBar.Maximum = emailPKs.Count;
>>>>>>>> progressBar.Minimum = 0;
>>>>>>>>
>>>>>>>> List<Task> tasks = new List<Task>();
>>>>>>>> var ui = TaskScheduler.FromCurrentSynchronizationContext();
>>>>>>>>
>>>>>>>> foreach (var id in emailPKs)
>>>>>>>> {
>>>>>>>> var send = Task.Factory.StartNew(() =>
>>>>>>>> {
>>>>>>>> return SendEmail(id);
>>>>>>>> });
>>>>>>>> tasks.Add(send);
>>>>>>>>
>>>>>>>> var display = send.ContinueWith(result =>
>>>>>>>> {
>>>>>>>> txtInfo.Text += String.Format("Email to {0} - {1}{2}", send.Result.EmailId,
>>>>>>>> send.Result.Status.ToString(), Environment.NewLine);
>>>>>>>> progressBar.Value++ ;
>>>>>>>> }, ui)
>>>>>>>> ;
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> Task.Factory.ContinueWhenAll(tasks.ToArray(), result =>
>>>>>>>> {
>>>>>>>> txtInfo.Text += "Complete." + Environment.NewLine;
>>>>>>>> btnTask.IsEnabled = btnEmail.IsEnabled = true;
>>>>>>>> progressBar.Value = progressBar.Maximum;
>>>>>>>> }, CancellationToken.None, TaskContinuationOptions.None, ui);
>>>>>>>>
>>>>>>>> }
>>>>>>>>Snag is SMTP (if that's what you are using) may not be able to handle being hit from all directions :-{
>>>>>>>
>>>>>>>Hmm, interesting stuff Viv. I may make use of it elsewhere for updating a table with 4000 odd updates, Unless that might be a problem too.
>>>>>>
>>>>>>If you mean updating an ADO.NET Datatable then I don't think it would work - Datatable is threadsafe for reads but not for writes.
>>>>>>
>>>>>>One addition to .NET 4.5 (if you are using it) is the BindingOperations.EnableCollectionSyncronization() method. If you have a collection databound to the UI this will enable you to update it on a different thread with the UI automatically updated. See:
http://dotnet.dzone.com/articles/wpf-45-%E2%80%93-part-7-accessing for a simple example. Since you originally wanted to update a DataGrid the approach might well be worth exploring....
>>>>>
>>>>>Unfortunately I'm on .NET 4.0 :(
>>>>
>>>>Upgrade ! :-}
>>>>In addition to the changes in the core framework there are some nice WPF improvements:
http://msdn.microsoft.com/en-us/library/bb613588.aspx>>>
>>>I wish :( project has gone over budget and I can't afford to upgrade at the moment
>>
>>If you can work with VS2012 Express for Windows it shouldn't cost you anything ?
>>Haven't tried it but the main shortcoming seems to be lack of support for third party extensibility (e.g. can't use Resharper etc.)
>
>Not just the cost of visual studio, but the time to recompile, test, distribute and fix any problems encountered.
I've upgraded half-a-dozen or so projects from VS2010/.NET4.0 to 4.5 on VS2012 and can't remember any problems at all. Can't say whether going to VSE2012 would be equally straightforward tho.....