I've built a library that launches a thread to do it's thing and returns a WaitHandle to the caller.

Looking at a bug report, I suspect the code that's calling my library is taking the returned object and casting it to an AutoResetEvent (which it is) and raising the flag itself. It's not meant to do that.

Is there a way I can wrap the AutoResetEvent object with one that can still be WaitOne'd and WaitAny'd, but can only be raised by my code?

Thanks.

有帮助吗?

解决方案

You can create a new class derived from EventWaitHandle and override Set and Reset so they do nothing, or throw an exception. Actually, you would have to create new implementations, since Set and Reset aren't virtual. Of course, you'd have to create your own, other-named methods. Like MyInternalSet and MyInternalReset. Possible, but I wouldn't recommend doing it.

Instead I would document that the client should not set or reset the event, because doing so will cause unpredictable behavior.

You could create a WaitHandle-derived class that holds your AutoResetEvent as an internal property. Client code then wouldn't be able to access it. Something like:

public class MyWaitHandle: WaitHandle
{
    internal AutoResetEvent InternalEvent { get; private set; }
    internal MyWaitHandle(AutoResetEvent event)
    {
        InternalEvent = event;
    }

    public override bool WaitOne(int32 timeout)
    {
        return InternalEvent.WaitOne();
    }
}

You'll have to override the protected Dispose(Boolean) method, so that it will dispose the internal handle, and you'll want the other WaitOne overloads, as well. You can then create internal implementations of Set and Reset, or just have your code call InternalHandle.Set.

I still think the best course of action is to tell the client not to do that. But if you must prevent it, the above should work.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top