To myself: Remember the following
Silverlight is “normally” hosted in the browser.
So, the single UI Thread should belong to the browser.
You can either learn that from different blogs, presentations or you learn it the hard way, like myself.
---------
In my current Silverlight app that I am working on, we have a Thread (System.Threading) that does some background jobs for us…
On the UI we display some progress and let the user stop this background job.
We do the stopping of the thread with the following lines of code.
private void StopImportantBackgroundJob() { if (_isRunningImportantBackgroundJob) { _isRunningImportantBackgroundJob = false; _biddingThread.Join(); _biddingThread = null; } UiUpdateImportantBackgroundJobControls(); }
So we
- Set our flag that enables the running thread
- Wait (Join) for the thread to get his job done
- Set the thread to null
Now. This Thread.Join() can take quite a long time, and means that the UI thread has to wait for the background thread.
What happens then is that you get this nice screen
Figure: The whole browser freezes – because Silverlight is blocking the UI thread
Note
Different browsers behave slightly different:
(Depending from their Process/Threading model)
- Chrome 4.1.249: All open tabs freeze, even different browser windows. I would expect to see only the current tab freeze, because each tab should be in its own process, as per this nice comic by Scott McCloud (definitely check this out and afterwards buy his book “Understanding Comics”!)
- Firefox 3.6.3: All open tabs freeze, even different browser windows
- IE 8.0.7600: Only the current browser window with all tabs freeze completely, other browser windows are responsive
How can we fix that?
- Don’t call Join(), so we don’t have to wait for the long job to finish
- Stop the long running thread by having a flag that the background thread checks every now and then…
- If flag is true: Continue running
- If flag is false: Sleep a little (instead of destroying thread), maybe user wants to continue later…
Maybe I should show you the code instead of using my own words ;-)
Things to avoid in the UI thread
- Long running tasks :-)
- Waiting for other threads
- Join()
- Sleep()
Timers
Things to avoid in the UI thread – with timers
- Timer’s that use the Dispatcher.BeginInvoke and do something expensive
- DispatcherTimer’s that do something expensive
Rule of thumb for timers
Use Timer (that runs on a separate thread) to do some number crunching or other tasks that don’t require to update the UI.
Use DispatcherTimer if you need to update the UI. Event is fired on the same thread as the Dispatcher…
No comments:
Post a Comment