John Carpenter John Carpenter - 1 month ago 10
C# Question

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?

Answer

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.