ObservablePriorityQueue Implementation I have a requirement in my current project that will need a Prioritised Queue that supports the IObservable interface. Please notify me of any problems with the implementation that I currently have:

ObservablePriorityQueue&lt;T&gt;

public sealed class ObservablePriorityQueue&lt;T&gt; : IQueue&lt;T&gt;, IObservable&lt;T&gt; where T : IPrioritised
{
    #region "IObservable&lt;T&gt; Implementation"
    // A list of the subscribers for the IObservable implementation
    List&lt;IObserver&lt;T&gt;&gt; _subscribers = new List&lt;IObserver&lt;T&gt;&gt;(10);

    Object _observableSyncLock = new Object();

    #region "Interface specific"
    public IDisposable Subscribe(IObserver&lt;T&gt; observer)
    {
        if (observer == null)
        {
            throw new ArgumentNullException("The observer cannot be null.");
        }

        if (!_subscribers.Contains(observer))
        {
            lock (_observableSyncLock)
            {
                _subscribers.Add(observer);
            }
        }

        return new Disposable(() =&gt;
        {
            this.Unsubscribe(observer);
        });
    }
    #endregion

    public void Unsubscribe(IObserver&lt;T&gt; observer)
    {
        if (observer == null)
        {
            throw new ArgumentNullException("The observer cannot be null.");
        }

        observer.OnCompleted();

        if (_subscribers.Contains(observer))
        {
            // remove the entry, but don't dispose it just 
            // in case they want to re-subscribe with the same observer later
            lock (_observableSyncLock)
            {
                _subscribers.Remove(observer);
            }
        }
    }
    #endregion

    #region "IQueue&lt;T&gt; Implementation"

    readonly List&lt;T&gt; _data = new List&lt;T&gt;(100);
    Object _queueSyncLock = new Object();

    public void Enqueue(T value)
    {
        if (value == null)
        {
            throw new ArgumentException("The item to be enqueued cannot be null");
        }

        lock (_queueSyncLock)
        {
            _data.Add(value);
        }

        // now that the entry has been added, notify everyone
        Task.Run(() =&gt;
        {
            lock (_observableSyncLock)
            {
                foreach (IObserver&lt;T&gt; subscriber in _subscribers)
                {
                    subscriber.OnNext(value);
                }
            }
        });
    }

    public T Dequeue()
    {
        if (_data.Count &gt; 0)
        {
            lock (_queueSyncLock)
            {
                var result = _data.OrderByDescending(element =&gt; element.Priority).ThenBy(element =&gt; element.TimeStamp).First();
                _data.Remove(result);
                return result;
            }
        }
        return default(T);
    }

    public T Peek()
    {
        if (_data.Count &gt; 0)
        {
            return _data.OrderByDescending(element =&gt; element.Priority).ThenBy(element =&gt; element.TimeStamp).First();
        }
        return default(T);
    }

    public Int32 Count { get { return _data.Count; } }
    #endregion
}


IQueue&lt;T&gt;

public interface IQueue&lt;T&gt;
{

    void Enqueue(T value);
    T Dequeue();
    T Peek();

    Int32 Count { get; }
}


IPrioritised&lt;T&gt;

public interface IPrioritised
{
    QueuePriority Priority { get; }
    DateTime TimeStamp { get; }
}


QueuePriority

public enum QueuePriority
{
    None = 0,
    Lowest = 1,
    Low = 2,
    Normal = 3,
    High = 4,
    Highest = 5
}


Disposable

public sealed class Disposable : IDisposable
{
    readonly Action _action;
    public Disposable(Action action)
    {
        _action = action;
    }
    public void Dispose()
    {
        if (_action != null)
        {
            _action();
        }
    }
}
At first, I was confused what exactly did the implementation of IObservable&lt;T&gt; mean. You should properly document that.
You don't need to have a separate lock objects. If you're locking on a specific object, I think you should use that object in the lock.
If you're just calling a single method in your lambda, you can use more succinct syntax: new Disposable(() =&gt; this.Unsubscribe(observer)).
If you want to make your code thread-safe, you need to lock all your reads too. In Unsubscribe() you don't do that, which means someone could write to the list while you're reading it. The same problem is in Peek().
Dequeue() shouldn't return default(T) if the queue is empty. This can be problematic especially with value types. Instead, you should have a method like bool TryDequeue(out T result).
You're accessing Count outside of a lock. I wouldn't rely on the fact that doing this is safe, I think you should lock before accessing it too.
Since you're using Rx, you might as well use their Disposable.Create() instead of creating your own.