How can I subclass WaitHandle?

Is it possible (in a meaningful way)?

For example, let's say I would like to implement a pending queue like this:

public class WaitableQueue : WaitHandle {
    public WaitableQueue() {
      q = new Queue();
    }

    public void Enqueue(Object Arg) {
      lock(this) {
        q.Enqueue(Arg);
        // set the waithandle here (how?)
      }
    }

    public Type Dequeue() {
      lock(this) {
        if(q.Count == 1)
        // reset the waithandle here (how?)
        return q.Dequeue();
      }
    }

    Queue q;
  }

      

+1


source to share


4 answers


It is important to remember that you must set the property SafeWaitHandle

.

From MSDN:

When you exit WaitHandle, use the SafeWaitHandle property to save the operating system handle. You don't need to override the protected Dispose method unless you are using additional unmanaged resources.

This is how I will do it.



public class QueueWaitHandle<T> : WaitHandle
{
    private Queue<T> queue = new Queue<T>();
    private ManualResetEvent signal = new ManualResetEvent(false);

    public QueueWaitHandle()
    {
        base.SafeWaitHandle = signal.SafeWaitHandle;
    }

    public void Enqueue(T item)
    {
        lock (queue)
        {
            queue.Enqueue(item);
            signal.Set();
        }
    }

    public T Dequeue()
    {
        lock (queue)
        {
            T item = queue.Dequeue();
            if (queue.Count == 0)
            {
                signal.Reset();
            }
            return item;
        }
    }
}

      

It Enqueue

acts as a method Set

and Dequeue

acts as a method Reset

. So it basically works like a counting event where a non-zero signal is signaled and a zero is not signaled. In this case, the queue does the count, and the data is simply stored.

I know you asked about subclassing WaitHandle

in general, but this particular data structure is more than just an exercise. This can be useful in some scenarios. However, I would not call it an awaited queue, because that means, at least to me, that the operation Dequeue

will block when the queue is empty. Clearly this is not what will happen in this particular implementation.

+7


source


The EventWaitHandle class has a Set and Reset method, so you can inherit from it instead of WaitHandle.

However, I would say that for the example provided, I don't think that would be a good implementation, because the SafeWaitableQueue class now has two different roles: a queue and a wait handle.



But if you have anything else where you need to implement your own wait handle, I would suggest trying inheriting from EventWaitHandle.

This is not a great solution because the Set and Reset methods are publicly exposed, which means that users of your SafeWaitableQueue class can also call Set and Reset, which will likely result in some un safe behavior.

+3


source


I would create a class that combines both Queue AND WaitHandle, like so:

public class WaitableQueue<T>
{
    private Queue<T> _queue;
    private WaitHandle _waitHandle;

    public WaitableQueue()
    {
        _queue = new Queue<T>();
        _waitHandle = new WaitHandle();
    }

    public void Enqueue(T Arg) {
      lock(this) {
        _queue.Enqueue(Arg);
        _waitHandle.Set();
      }
    }
    ...
}

      

+1


source


I think this does not inherit very well. Your object is a queue and uses a wait handle for thread safety, so you don't have to be retrieved from a WaitHandle.

0


source







All Articles