繁体   English   中英

Readonly WaitHandle C#

[英]Readonly WaitHandle C#

我在一个接口上为一个负责在内部创建资源的对象公开WaitHandle ,但这可能需要很长时间。 合同如下:

public interface IHaveExpensiveResources {
    WaitHandle FinishedInitialization { get; }
}

WaitHandle开始取消设置,但是我在初始化完成后设置它(在后台,在构造函数返回之后)。 我不喜欢的是这个合同的消费者可以自己设置WaitHandle ,当他们没有业务能够做到这一点时。 它让我想起了get-only IList<T>属性和IReadOnlyList<T>之间的区别。

C#中有没有像WaitOnlyWaitHandle只暴露WaitOne()重载方法的东西?

因此,我不是XY问题的受害者,是否有更规范的方法来异步构建具有较长构造时间的对象?

你是否必须传回一个WaitHandle或者你可以创建自己的包装类,只暴露你想要的函数,类似于ReadOnlyCollection的作用?

一种选择是将WaitHandle包装到任务中(从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;
}

然后你只需要调用.WaitOneAsync()就可以返回任何FinishedInitialization并返回该Task

为了完整性,这是我为WaitHandle上的WaitOne()重载方法公开而创建的接口和实现

public interface IWaitOnlyWaitHandle
{
    bool WaitOne();
    bool WaitOne(TimeSpan timeout);
    bool WaitOne(int millisecondsTimeout);
    bool WaitOne(int millisecondsTimeout, bool exitContext);
    bool WaitOne(TimeSpan timeout, bool exitContext);
}

public sealed class WaitOnlyWaitHandle : IWaitOnlyWaitHandle
{
    # UPDATE: this object does not own the passed in WaitHandle
    private readonly WaitHandle _waitHandle;
    public WaitOnlyWaitHandle(WaitHandle waitHandle)
    {
        _waitHandle = waitHandle;
    }

    public bool WaitOne() => _waitHandle.WaitOne();
    public bool WaitOne(TimeSpan timeout) => _waitHandle.WaitOne(timeout);
    public bool WaitOne(int millisecondsTimeout) => _waitHandle.WaitOne(millisecondsTimeout);
    public bool WaitOne(int millisecondsTimeout, bool exitContext) => _waitHandle.WaitOne(millisecondsTimeout, exitContext);
    public bool WaitOne(TimeSpan timeout, bool exitContext) => _waitHandle.WaitOne(timeout, exitContext);
}

更新:根据@ stevenbone的评论,此实现不拥有传递给构造函数的WaitHandle的生命周期。 阅读他的评论以获取更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM