Search code examples
c#asynchronouswaithandle

Readonly WaitHandle C#


I am exposing a WaitHandle on an interface for an object that's responsible for creating a resource internally, but it may take a long time. The contract looks like this:

public interface IHaveExpensiveResources {
    WaitHandle FinishedInitialization { get; }
}

The WaitHandle starts unset, but then I set it once the initialization completes (in the background, after the constructor returns). The thing I don't like about this is that consumers of this contract can set the WaitHandle themselves, when they have no business being able to do this. It reminds me of the difference between a get-only IList<T> property and a IReadOnlyList<T>.

Is there anything in C# like a WaitOnlyWaitHandle which only exposes the WaitOne() overloaded methods?

So that I'm not a victim of the XY problem, is there a more canonical way of asynchronously constructing objects which have long construction times?


Solution

  • Do you have to pass back a WaitHandle or could you make your own wrapper class that only exposes the functions you want, similar to what ReadOnlyCollection does?

    One option is to wrap the WaitHandle up in to a task (Code example taken from the MSDN)

    public static Task WaitOneAsync(this WaitHandle waitHandle)
    {
        if (waitHandle == null) 
            throw new ArgumentNullException("waitHandle");
    
        var tcs = new TaskCompletionSource<bool>();
        var rwh = ThreadPool.RegisterWaitForSingleObject(waitHandle, 
            delegate { tcs.TrySetResult(true); }, null, -1, true);
        var t = tcs.Task;
        t.ContinueWith( (antecedent) => rwh.Unregister(null));
        return t;
    }
    

    Then you just call .WaitOneAsync() on whatever FinishedInitialization would have been returning and return that Task instead.