将ManualResetEvent包装为等待任务
我想等待手动重置事件,超时并观察取消。 我想出了类似下面的东西。 手动重置事件对象由我无法控制的API提供。 有没有办法在不接受和阻止ThreadPool的线程的情况下实现这一点?
static Task TaskFromWaitHandle(WaitHandle mre, int timeout, CancellationToken ct) { return Task.Run(() => { bool s = WaitHandle.WaitAny(new WaitHandle[] { mre, ct.WaitHandle }, timeout) == 0; ct.ThrowIfCancellationRequested(); return s; }, ct); } // ... if (await TaskFromWaitHandle(manualResetEvent, 1000, cts.Token)) { // true if event was set } else { // false if timed out, exception if cancelled }
[已编辑]显然,使用RegisterWaitForSingleObject
是有意义的 。 我试一试。
RegisterWaitForSingleObject
将等待组合到专用的服务器线程上,每个线程都可以在多个句柄上等待(具体来说,其中63个, MAXIMUM_WAIT_OBJECTS
减去一个“控制”句柄)。
所以你应该可以使用这样的东西(警告:未经测试):
public static class WaitHandleExtensions { public static Task AsTask(this WaitHandle handle) { return AsTask(handle, Timeout.InfiniteTimeSpan); } public static Task AsTask(this WaitHandle handle, TimeSpan timeout) { var tcs = new TaskCompletionSource
您还可以使用与ManualResetEvent类似的SemaphoreSlim.WaitAsync()