首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Readonly WaitHandle C#

Readonly WaitHandle C#
EN

Stack Overflow用户
提问于 2016-05-27 18:21:23
回答 2查看 120关注 0票数 2

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

代码语言:javascript
复制
public interface IHaveExpensiveResources {
    WaitHandle FinishedInitialization { get; }
}

WaitHandle将启动unset,但在初始化完成后(在后台,在构造函数返回后),我会设置它。我不喜欢的是,这个合同的消费者可以自己设置WaitHandle,当他们没有能力这样做的时候。这让我想起了IList属性和IReadOnlyList属性之间的区别。

C#中有什么东西像WaitOnlyWaitHandle那样只公开WaitOne()重载的方法吗?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-27 18:30:47

您必须传回一个WaitHandle,还是您可以创建您自己的包装类,它只公开您想要的函数,类似于ReadOnlyCollection所做的?

一种选择是将WaitHandle封装到一个任务中(从MSDN获取代码示例)

代码语言:javascript
复制
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

票数 4
EN

Stack Overflow用户

发布于 2016-05-27 18:43:51

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

代码语言:javascript
复制
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的生命周期。阅读他的评论,以获得更多信息。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37490044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档