只读 WaitHandle C#
Readonly WaitHandle C#
我正在为负责在内部创建资源的对象的接口公开一个 WaitHandle
,但这可能需要很长时间。合同如下所示:
public interface IHaveExpensiveResources {
WaitHandle FinishedInitialization { get; }
}
WaitHandle
开始未设置,但我在初始化完成后设置它(在后台,在构造函数 returns 之后)。我不喜欢这个的一点是,这个合同的消费者可以自己设置 WaitHandle
,而他们没有业务可以这样做。这让我想起了 get-only IList<T>
property and a IReadOnlyList<T>
.
之间的区别
C# 中是否有类似 WaitOnlyWaitHandle
的东西,它只公开 WaitOne()
重载方法?
所以我不是 XY 问题的受害者,是否有更规范的异步构造构造时间长的对象的方法?
您是否必须传回一个 WaitHandle
或者您是否可以制作自己的包装器 class 只公开您想要的功能,类似于 ReadOnlyCollection 所做的?
一个选项是将 WaitHandle 包装到任务中(代码示例取自 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;
}
然后你只需调用 .WaitOneAsync()
任何 FinishedInitialization
本来 returning 和 return 而 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
的生命周期。阅读他的评论以获取更多信息。
我正在为负责在内部创建资源的对象的接口公开一个 WaitHandle
,但这可能需要很长时间。合同如下所示:
public interface IHaveExpensiveResources {
WaitHandle FinishedInitialization { get; }
}
WaitHandle
开始未设置,但我在初始化完成后设置它(在后台,在构造函数 returns 之后)。我不喜欢这个的一点是,这个合同的消费者可以自己设置 WaitHandle
,而他们没有业务可以这样做。这让我想起了 get-only IList<T>
property and a IReadOnlyList<T>
.
C# 中是否有类似 WaitOnlyWaitHandle
的东西,它只公开 WaitOne()
重载方法?
所以我不是 XY 问题的受害者,是否有更规范的异步构造构造时间长的对象的方法?
您是否必须传回一个 WaitHandle
或者您是否可以制作自己的包装器 class 只公开您想要的功能,类似于 ReadOnlyCollection 所做的?
一个选项是将 WaitHandle 包装到任务中(代码示例取自 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;
}
然后你只需调用 .WaitOneAsync()
任何 FinishedInitialization
本来 returning 和 return 而 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
的生命周期。阅读他的评论以获取更多信息。