ManualResetEvent到IObservable <bool>(或WaitHandle到IObservable <unit>)?

时间:2017-06-01 10:14:51

标签: c# multithreading system.reactive

我想基于ManualResetEvent的Sets / Resets创建一个IObservable-stream,例如:原则上像

IObservable<bool> ToObservable(ManualResetEvent ev)
{
  var s = new Subject<bool>();
  ev.OnSet += s.OnNext(true);
  ev.OnReset += s.OnNext(false);
  return s;
}

当然,只有ManualResetEvent不会公开此类事件。那么当它被停止/重置时有什么方法可以观察吗?

对于记录,如果不能将set / unset设置为true / false,则更简单的IObservable&lt; Unit&gt;只要ManualResetEvent的状态发生变化,就可以推送一个值。

有没有办法做到这一点?

我发现了一篇文章,解释了如何将ManualResetEvent(或者更确切地说是一个WaitHandle)转换为任务(Wrapping ManualResetEvent as awaitable task),这似乎在下次是ManualResetEvent更改时完成(来自设置为取消设置,或其他方式)。 但是我还没有找到任何方法可以将它链接到一个序列中(例如,在任务完成之后,我需要为下一个事件创建另一个事件,等等,并以某种方式创建一个可观察的“递归“序列”

谢谢!

1 个答案:

答案 0 :(得分:0)

有很多不同的方法可以做到这一点,但有些事情是这样的:

public static class ManualResetEventObservable
{
    public static IObservable<bool> Create(ManualResetEvent e, TimeSpan timeout)
    {
        return Observable.Create<bool>(observer =>
        {
            var cancelEvent = new ManualResetEvent(false);
            var waitHandles = new[] { cancelEvent, e };
            var thread = new Thread(new ThreadStart(() =>
            {
                var index = WaitHandle.WaitAny(waitHandles, timeout);
                if (index == 1)
                    observer.OnNext(true);

                observer.OnCompleted();
            }));
            thread.Start();
            return Disposable.Create(() => cancelEvent.Set());
        });
    }