C#•Implement the DelegateSerializer

Listing 5. The DelegateSerializer class implements a thread-safe mechanism that receives a delegate and its invocation parameters from a client. The class stores the delegate in an internal Queue object and immediately returns the control back to the caller. When a delegate is put in the queue, an AutoResetEvent wakes up a threat, which pulls messages from the queue, then extracts the delegate and calls it synchronously.

using System;
using System.Threading;
using System.Collections;

public class DelSerializer {
	//use a Synchronized object so you don't 
	//have to worry about thread concurrency 
	private readonly Queue m_queue = Queue.Synchronized(
		new Queue());
	private readonly AutoResetEvent m_event ;
	// the worker thread
	private readonly Thread m_thread ;

public DelSerializer(string name) {
	m_event = new AutoResetEvent(false);
	m_thread = new Thread(new ThreadStart (Run));
	m_thread.Name = name;
	m_thread.IsBackground = true;
	m_thread.Start();
}

private void Run() {
	QueueElement obj =null;
	do {
		m_event.WaitOne();
		while(IsEmpty()==false) {
			obj = (QueueElement)Dequeue();
			try	{
			//call delegate
				obj.del.DynamicInvoke(obj.parameters ); }
			catch (Exception ex) {
				//log exceptions
				System.Diagnostics.Debug.WriteLine 
					(ex.Message);	 
			}
		}
	} while (obj ==null); 
	// Allow a way to end the thread
}
	
public void Enqueue(Delegate del, object[] 
	parameters) {
	if(del ==null) 
		m_queue.Enqueue(null);
	else
		m_queue.Enqueue(new QueueElement 
			(del,parameters));
	// Tell the worker thread there are values...
	m_event.Set();
}

private object Dequeue() {
	return m_queue.Dequeue();
}

public bool IsEmpty() {
	return m_queue.Count == 0;
}

//The auxiliary class to post Delegates and method 
//parameters to the Queue
public class QueueElement {
	public QueueElement(Delegate p_del ,object[] 
		p_parameters) {
		del = p_del;
		parameters= p_parameters;
	}
	public Delegate del;
	public object[] parameters;
}
}