Classes to handle the multithreading aspects in applications.

Classes

  ClassDescription
Public classDelegateTask
Executes DelegateTask.CallBack in IDispatcher thread. Usually used in synchronization with GUI thread.
Public classExceptionEventArgs
Event arguments to execute ITask in the IDispatcher's thread
Public classGuiDispatcher
Executes tasks in GUI thread.

Interfaces

  InterfaceDescription
Public interfaceIDispatcher
Executes ITask objects with or without blocking the calling thread
Public interfaceITask
Represents a task, that can be executed in the IDispatcher thread

Delegates

  DelegateDescription
Public delegateDelegateTask..::..CallBack
DelegateTask..::..CallBack delegate that is called in IDispatcher thread. Usually used in synchronization with GUI thread.

Remarks

All Wpf controls are single-threaded, which means that their methods can be called only in thread where they are running, i.e. the GUI thread. To make sure that application will run safely, you have to synchronize threads. There are two types of synchronization: synchronous and asynchronous. These types are available via Dispatcher.Invoke() and Dispatcher.BeginInvoke() methods accordingly. The main difference between these two methods is that synchronous calls block the calling thread until the end of Dispatcher.Invoke() function call, while asynchronous calls block the thread only for the time while a delegate is added to the queue.

The GridControl is a thread-safe Wpf component. When the grid receives notifications from INotifyPropertyChanged and IBindingList, it performs synchronization with its own thread, thus removing the need to perform synchronization at the data layer and to implement unnecessary references to graphical controls.

 Copy imageCopy
<--MainWindow.xaml-->
<Window x:Class="WpfApplication1.MainWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:Controls="clr-namespace:Dapfor.Wpf.Controls;assembly=Dapfor.Wpf" 
   Title="Dapfor Wpf Grid: Threadsafety" Height="200" Width="405">

   <Grid>
       <Controls:GridControl Name="dataGrid">
           <Controls:GridControl.Headers>
               <Controls:Header ScrollType="Stretch">
                   <Controls:Header.Columns>
                       <Controls:Column Id="Name" Title="Name" />
                       <Controls:Column Id="Price" Title="Price" />
                   </Controls:Header.Columns>
               </Controls:Header>
           </Controls:GridControl.Headers>
       </Controls:GridControl>
   </Grid>
</Window>


//Simple feed item
public class Feed : INotifyPropertyChanged
{
    //...
}


//Interaction logic for MainWindow.xaml
public partial class MainWindow : Window
{
    private readonly BindingList<Feed> _feeds = new BindingList<Feed>();

    public MainWindow()
    {
        InitializeComponent();

        //Add some items to the collection
        _feeds.Add(new Feed("Feed1", 10));
        _feeds.Add(new Feed("Feed2", 20));

        ////Bind the grid to the source
        dataGrid.ItemsSource = _feeds;


        //Add a new item in the non-UI thread
        ThreadPool.QueueUserWorkItem(delegate
        {
            _feeds.Add(new Feed("Feed3", 30));
        });

        //Update item in the non-UI thread
        ThreadPool.QueueUserWorkItem(delegate
        {
            _feeds[1].Price = 40;
        });
    }
}