ThreadSafeObservableCollection of (T) The idea here is to implement a simple, threadsafe, observable collection that clients can bind to, whilst background threads can update. Changes in the contained items raise the CollectionChanged event. 

Feedback appreciated:

public class ThreadSafeObservableCollection&lt;T&gt; : INotifyCollectionChanged
    where T: INotifyPropertyChanged
{
    private readonly Object _lock = new Object();
    private readonly Collection&lt;T&gt; _items = new Collection&lt;T&gt;();
    private ReadOnlyCollection&lt;T&gt; _readonlyItems;

    public ThreadSafeObservableCollection()
    {

    }

    public ThreadSafeObservableCollection(IEnumerable&lt;T&gt; items)
    {
        _items = new ObservableCollection&lt;T&gt;(items);
        foreach (T item in _items)
        {
            ((INotifyPropertyChanged) item).PropertyChanged += ItemPropertyChangedHandler;
        }  
    }

    public ReadOnlyCollection&lt;T&gt; Items
    {
        get { return _readonlyItems ?? (_readonlyItems = new ReadOnlyCollection&lt;T&gt;(_items)); }
    }

    public virtual void Add(T obj)
    {
        lock(_lock)
        {
            ((INotifyPropertyChanged) obj).PropertyChanged += ItemPropertyChangedHandler;
            _items.Add(obj);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, obj));
        }
    }

    public virtual void Remove(T obj)
    {
        lock (_lock)
        {
            ((INotifyPropertyChanged) obj).PropertyChanged -= ItemPropertyChangedHandler;
            _items.Remove(obj);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, obj));
        }
    }


    #region INotify Members

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
    {
        var copy = CollectionChanged;
        if(copy != null)
        {
            CollectionChanged(this, args);
        }
    }

    private void ItemPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
    {
        NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
        OnCollectionChanged(args);
    }

    #endregion
}


Update

In response to the comments about the ReadOnlyCollection, I have switch its implementation for a yield block that is locked (Using a ReaderWriterLock) for the length of the enumeration, like so:

    public IEnumerable&lt;T&gt; Items
    {
        get
        {
            _lock.AcquireReaderLock(_lockTimeout);
            try
            {
                foreach (T item in _items)
                {
                    yield return item;
                }
            }
            finally
            {
                _lock.ReleaseReaderLock();
            }
        }
    }


Any thoughts?
Your Items initialization I believe isn't threadsafe. Use Lazy&lt;T&gt; for thread safe lazy initialization instead.
The ReadOnlyCollection isn't thread safe.

A ReadOnlyCollection can support
multiple readers concurrently, as long
as the collection is not modified.
Even so, enumerating through a
collection is intrinsically not a
thread-safe procedure. To guarantee
thread safety during enumeration, you
can lock the collection during the
entire enumeration. To allow the
collection to be accessed by multiple
threads for reading and writing, you
must implement your own
synchronization.

Consider using a ReaderWriterLock to support a single writer, but multiple readers.

Furthermore, consider reading this reply, and the blog post mentioned there, which discusses why thread safe collections are so hard, and not necessarily useful.