The grid itself is thread-safe. However, it can address data from GUI thread, and if this data is used in a non-GUI thread, they should be protected. Please see below a typical method of data object protection in event-driven model.

C# Copy imageCopy
//Some data object. The grid itself is threadsafe.
//The responsibility of the programmer - is to implement a threadsafe object 
//if he wants to use it in different threads
public class Product : INotifyPropertyChanged
{
    //Some fields
    private double price;
    private DateTime maturity;

    //Threadsafe implementation of the event
    PropertyChangedEventHandler internalPropertyChanged;
    readonly object synchro = new object();

    //Thread-safe implementation of the 'Price' property
    public double Price
    {
        get
        {
            lock (synchro)
            {
                return price;
            }
        }
        set
        {
            lock (synchro)
            {
                price = value;
            }
            NotifyPropertyChanged("Price");
        }
    }

    public DateTime Maturity
    {
        get { return maturity; }
    }

    private void NotifyPropertyChanged(string property)
    {
        //Send notification without acquiring the synchro object
        PropertyChangedEventHandler localCopy;
        lock (synchro)
        {
            localCopy = internalPropertyChanged != null ? (PropertyChangedEventHandler)internalPropertyChanged.Clone() : null;
        }

        if(localCopy != null)
        {
            localCopy(this, new PropertyChangedEventArgs(property));
        }
    }

    //By default the event implementation is not threadsafe.
    //We will do a thread-safe implementation of the event
    public event PropertyChangedEventHandler PropertyChanged
    {
        add
        {
            lock (synchro)
            {
                internalPropertyChanged += value;
            }
        }
        remove
        {
            lock (synchro)
            {
                internalPropertyChanged -= value;
            }
        }
    }
}

public void PopulateGrid(Grid grid)
{
    //Add data object to the grid from the calling thread. 
    grid.Rows.Add(new Product());

    //Create other product
    Product otherProduct = new Product();

    //Add the product to the Grid from other thread - it is safe
    ThreadPool.QueueUserWorkItem(delegate
    {
        //Add the product
        grid.Rows.Add(otherProduct);

        //Update the property. The object will notify the grid from the non-GUI thread.
        //The grid will synchronize threads without blocking the calling thread. 
        //Then it will ask for a new value from the GUI thread and refresh, sort and filter appropriate rows if needed. 
        otherProduct.Price = 12.33;
    });
}

Back to .Net Grid HowTo topics