You can do this more elegantly using the BackgroundWorker class.
XAML for the Button:
<Button x:Name="btnGo" Content="Send" Click="btnGo_Click"></Button>
Code :
private BackgroundWorker _worker; public MainWindow() { InitializeComponent(); _worker = new BackgroundWorker(); _worker.WorkerSupportsCancellation = true; _worker.WorkerReportsProgress = true; } private void btnGo_Click(object sender, RoutedEventArgs e) { _worker.RunWorkerCompleted += delegate(object completedSender, RunWorkerCompletedEventArgs completedArgs) { Dispatcher.BeginInvoke((Action)(() => { btnGo.Content = "Send"; })); }; _worker.DoWork += delegate(object s, DoWorkEventArgs args) { Dispatcher.BeginInvoke((Action)(() => { btnGo.Content = "Cancel"; })); SendImage sendImage = args.Argument as SendImage; if (sendImage == null) return; var count = 0; while (!_worker.CancellationPending) { Dispatcher.BeginInvoke((Action)(() => { btnGo.Content = string.Format("Cancel {0} {1}", sendImage.Name, count); })); Thread.Sleep(100); count++; } }; if (_worker.IsBusy) { _worker.CancelAsync(); } else { _worker.RunWorkerAsync(new SendImage() { Name = "Test" }); } }