我怎样才能将WaitHandle子类化?
是否有可能(以有意义的方式)?
例如,假设我想实现一个可等待的队列,如下所示:
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; }
要记住的重要一点是,您必须设置SafeWaitHandle
属性。
来自MSDN:
从WaitHandle派生时,使用SafeWaitHandle属性存储本机句柄操作系统句柄。 除非使用其他非托管资源,否则不需要覆盖受保护的Dispose方法。
我就是这样做的。
public class QueueWaitHandle : WaitHandle { private Queue queue = new Queue (); 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; } } }
当这样做时, Enqueue
就像Set
方法一样, Dequeue
就像Reset
方法一样。 所以基本上这就像一个计数事件,其中非零信号,零无信号。 在这种情况下,队列正在进行计数,它恰好也会保存数据。
我知道你一般都在询问子类化WaitHandle
,但这个特定的数据结构不仅仅是一个练习。 它在某些情况下很有用。 但是,我不会将其称为可等待的队列,因为这至少对我来说意味着Dequeue
操作将在队列为空时阻塞。 显然,这不是在这个特定的实现中会发生的事情。
EventWaitHandle类具有Set和Reset方法,因此您可以inheritance该方法而不是WaitHandle。
但是,我会说,对于提供的示例,我认为这不是一个好的实现,因为SafeWaitableQueue类现在有两个不同的角色:队列和等待句柄。
但是,如果你有其他需要实现自己的等待句柄的东西,我建议尝试从EventWaitHandleinheritance。
这不是一个很好的解决方案,因为Set和Reset方法是公开的,这意味着SafeWaitableQueue类的使用者也可以调用Set和Reset,这可能会导致一些明显不安全的行为。
我创建了一个聚合Queue和WaitHandle的类,所以:
public class WaitableQueue { private Queue _queue; private WaitHandle _waitHandle; public WaitableQueue() { _queue = new Queue (); _waitHandle = new WaitHandle(); } public void Enqueue(T Arg) { lock(this) { _queue.Enqueue(Arg); _waitHandle.Set(); } } ... }
我认为这不是对inheritance的好用。 您的对象是一个队列并使用等待句柄来提供线程安全性,因此您不应该从WaitHandle派生。