Is this Agent/Actor implementation issue free? I implemented this Agent class for a project recently and was wondering if I could get some other eyes to look at it -- I'm currently the only developer where I work so I can't exactly ask someone here to do it.

I'm pretty sure it's correct, but then I'm too close to it.

public abstract class Agent&lt;M&gt; : IDisposable
{
    private Thread thread;
    private Queue&lt;M&gt; messageQueue;
    private bool quit;

    public Agent()
    {
        this.thread = new Thread(new ThreadStart(AgentThreadBody));
        this.messageQueue = new Queue&lt;M&gt;();
        this.quit = false;

        this.thread.Start();
    }

    /// &lt;summary&gt;
    /// Stops the message-handling thread.
    /// 
    /// Do not call this method from within the message-
    /// handling method, or it will result in a deadlock
    /// (because this method waits for the message-handling
    /// thread to stop).
    /// &lt;/summary&gt;
    public virtual void Dispose()
    {
        this.quit = true;
        this.thread.Interrupt();
        this.thread.Join();
        this.thread = null;
        // clear messageQueue before nulling?
        // (would do this to dispose queued items)
        this.messageQueue = null;
    }

    public void QueueMessage(M message)
    {
        lock (this.messageQueue)
        {
            this.messageQueue.Enqueue(message);
            this.thread.Interrupt();
        }
    }

    private void AgentThreadBody()
    {
        while (!this.quit)
        {
            M message = default(M);
            bool messageAvailable = false;

            lock (messageQueue)
            {
                if (messageQueue.Count &gt; 0)
                {
                    message = messageQueue.Dequeue();
                    messageAvailable = true;
                }
            }

            try
            {
                if (!messageAvailable)
                {
                    // if the Interrupt() method was
                    // called before we sleep or is
                    // called while we're sleeping,
                    // this will throw:
                    // ThreadInterruptedException
                    Thread.Sleep(Timeout.Infinite);
                }
            }
            catch (ThreadInterruptedException)
            {
                // we have a new message to handle,
                // so get it, or we've been told
                // to quit.
                continue;
            }

            ProcessMessage(message);
        }
    }

    protected abstract void ProcessMessage(M message);
}


Also, are there any special considerations you can think of that should be made by a class inheriting from this base class? (I can't think of any.)

I could add start/stop methods, but at the moment they're not needed.

Btw, I have to use .NET 3.5.
Few minor points:


Generic type parameter should be called &lt;T&gt; as per convention.
public constructors in abstract classes make no sense - make it
protected.
Make thread and messageQueue readonly and don't
set them to null in the Dispose() method.
Better yet, implement the Disposable Pattern correctly. Though note, I do disagree with their setting of the IDisposable members to null. It's really not necessary at all; but calling Dispose() is. Their _disposed class member conveys enough information necessary.
You should also lock on a dedicated locking class member when accessing your quit class member since it is accessed via multiple threads.
Possibly wrap your call to ProcessMessage(message) in a try..catch block with appropriate error handling (or not, as the case could be). Unless, of course, you trust any subclasses from doing nasty things in their override of it.


Just my initial thoughts. Hope they help.