WPF

Threading in Windows Presentation Foundation


However it is technically possible for an application to have multiple dispatchers each on a different thread but each top level window needs to be on a single dispatcher. However its very common to have only one dispatcher for one WPF application. And also generally a WPF application has one UI thread but that’s not a constraint. So we cannot modify anything on the UI elements from the wrong thread means non UI thread directly. As all the user inputs are handled by the dispatcher so when we do any other task on that thread then the dispatcher will not be to handle the user input. So we should not block the UI thread to the functions that take long time to complete.
Async Work
The answer is to perform slow work asynchronously either by using multithreading or some API’s. If we want to update the UI in between these tasks then we can use the Dispatcher to come back on the right thread for updating the UI. We can do this by calling the Dispatcher.BeginInvoke method and passing the method delegate to it. This will end up as a message in the message queue of the dispatcher and when the dispatcher processes this message in its queue it will invoke the specified method and make eth updates to the UI thread. This will make sure that the UI updates will happen always on the right thread no matter what thread we are on











































Synchronization Context
Instead of using the Dispatcher.BeginInvoke we can use the SynchronizationContext.Post method to make the updates to the UI. This was introduced in the version 2.0 of .NET and also works for Windows Forms and ASP.NET. A dummy implementation for this is shown in below.
The major advantage of using this pattern is that we gain a lot on the efficiency of the pattern. Just like the concurrent threads work in the Windows Operating system, the same the way this implementation needs the CPU time at the start and end of the operation explicitly and the remaining work is done concurrently. Like if it’s an IO task then it’s handled asynchronously by specialized hardware. So the major advantage of this pattern is its efficiency and we manage thousands of network operations with a few threads

SynchronizationContext synchronizationContext = SynchronizationContext.Current;

ThreadStart threadStart = delegate
{
    DoLongRunningWork();
    synchronizationContext.Post(delegate
    {
        UpdateUI();
    }, null);
};
threadStart.BeginInvoke(delegate(IAsyncResult asyncResult)
{
    threadStart.EndInvoke(asyncResult);
}, null);

Thread Pool
Some components offer nothing but a synchronous blocking API. We saw this in the section where I showed you the TimeConsumingTask. So we need to go and manage the blocking and unblocking of the thread.
We could use a Thread Pool for it. .NET always provides pool of thread to do random work on random threads. .NET dynamically creates and destroys thread to meets the applications workload and this is really helpful in synchronizing the unhelpful synchronous components. You should remember that anytime we are using a delegate asynchronously we are using the thread pool internally.
The V1 and V2 of .NET asynchronous also use the thread pool in some implementations like the background worker class.
The only problem in working with thread pool is to get back to the UI thread when the work is done.

Databinding and Threading
In the previous sections we have seen how we can update the UI coming back from the worker thread. Now we will see how we can update the UI if we are using data binding. This is useful in the cases our data source is producing the change notifications. Add the following class and code to you application. This class will provide datasource which provides slow data. As we can see in the code the get accessor is fast but the set accessor is fetching the updates. The FetchNewData method simulates the slow operation. We are using the thread pool to get the work done and then we are sleeping on the thread for 5 seconds and then the property is updated. Also you can see that this class implements the INotifyPropertyChange to implement the change notifications










No comments:

Post a Comment