User interface

I created a simple WPF application and added a button to the default window. When I click on the button, the simulated long working method is called (simulated using Thread.Sleep (15000). I try to make the button asynchronously, despite the following online examples: the button and all the lock windows, as soon as I click and stay there until Thread.Sleep (...) ends.

Any ideas why this is happening?

Here is the code:

private void button1_Click(object sender, RoutedEventArgs e) { DoSomeAsyncWork(); } private void DoSomeAsyncWork() { System.Windows.Threading.Dispatcher.Run(); Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart( delegate() { Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => Thread.Sleep(15000))); } )); thread.Start(); } 
+7
source share
3 answers

You are returning a long operation to the user interface thread. Let me comment on your example:

 Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart( delegate() { // here we are in the background thread Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { // here we are back in the UI thread Thread.Sleep(15000); })); } )); 

So you should change your example as follows:

 Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart( delegate() { // here we are in the background thread Thread.Sleep(15000); // <-- do the long operation here Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { // here we are back in the UI thread // do stuff here that needs to update the UI after the operation finished })); } )); 

As already mentioned, it is easier to use the BackgroundWorker class. Here is an example:

 private void DoSomeAsyncWork() { BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += (sender, args) => { // do your lengthy stuff here -- this will happen in a separate thread Thread.Sleep(15000); } bw.RunWorkerCompleted += (sender, args) => { if (args.Error != null) // if an exception occurred during DoWork, MessageBox.Show(args.Error.ToString()); // do your error handling here // do any UI stuff after the long operation here ... } bw.RunWorkerAsync(); // start the background worker } 
+12
source

Using BeginInvoke , you are actually executing the code in the user interface thread.

You need to use this only when updating the user interface from the background thread. If you just have:

  Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart( delegate() { Thread.Sleep(15000); } )); 

I think it will work.

However, you do not raise the Completed event, so you have no way of knowing when (or really, if) the thread completed. Explore the BackgroundWorker class. It makes a big hard climb for you. You just need to connect your code to the DoWork method.

+3
source

All Articles