我如何子类化WaitHandle
本文关键字:WaitHandle 子类 何子类 | 更新日期: 2023-09-27 18:16:33
有可能吗?
例如,假设我想实现一个可等待队列,如下所示:
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
属性。
当你从WaitHandle派生时,使用SafeWaitHandle属性来存储本机句柄操作系统句柄。你不需要这么做覆盖受保护的Dispose方法,除非使用附加的非托管资源。
我是这样做的。
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;
}
}
}
当这样做时,Enqueue
的行为像Set
方法,Dequeue
的行为像Reset
方法。基本上这就像一个计数事件,非零是有信号的,零是没有信号的。在这种情况下,队列正在进行计数,并且它恰好也保存数据。
我知道你在问关于WaitHandle
子类化的问题,但是这个特定的数据结构不仅仅是一个练习。它在某些情况下是有用的。但是,我不会将其称为可等待队列,因为这意味着,至少对我来说,Dequeue
操作将在队列为空时阻塞。显然,在这个特定的实现中不会发生这种情况。
EventWaitHandle类有一个Set和Reset方法,所以你可以从它继承而不是WaitHandle。
然而,我想说的是,对于所提供的示例,我不认为这将是一个很好的实现,因为SafeWaitableQueue类现在有两个不同的角色:队列和等待句柄。
但是,如果你有其他的想法,你需要实现自己的等待句柄,我建议尝试从EventWaitHandle继承。
这不是一个很好的解决方案,因为Set和Reset方法是公开暴露的,这意味着你的SafeWaitableQueue类的消费者也可以调用Set和Reset,可能导致一些明显un安全的行为。
我将创建一个类来聚合Queue和WaitHandle,所以:
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();
}
}
...
}
我认为这不是继承的好用法。你的对象是一个队列,而使用一个等待句柄来提供线程安全,所以你不应该从WaitHandle派生。