我想要很好地利用Reactive Extensions for .NET (Rx),并希望获得一些关于执行一些基本任务的意见。为了说明我正在尝试做什么,我有一个人为的例子,其中我有一个带有异步事件的外部组件:
class Component {
public void BeginStart() { ... }
public event EventHandler Started;
}该组件通过调用BeginStart()来启动。此方法立即返回,稍后,当组件完成启动时,将激发Started事件。
我想通过包装组件并等待Started事件被触发来创建一个同步启动方法。这就是我到目前为止想出的:
class ComponentWrapper {
readonly Component component = new Component();
void StartComponent() {
var componentStarted =
Observable.FromEvent<EventArgs>(this.component, "Started");
using (var startedEvent = new ManualResetEvent(false))
using (componentStarted.Take(1).Subscribe(e => { startedEvent.Set(); })) {
this.componenet.BeginStart();
startedEvent.WaitOne();
}
}
}我想摆脱ManualResetEvent,我希望Rx有一个解决方案。但是怎么做呢?
发布于 2010-06-03 14:16:15
PL's answer对于你的规范来说是非常好的,但是我想你可能会得到更好的结果,不是用.First()来对抗RX,而是通过为你的组件创建一个可观察的对象来拥抱它:
public static IObservable<Unit> AsObservable(this Component component)
{
return Observable.Defer(() =>
{
component.BeginStart();
return Observable
.FromEvent<EventArgs>(component, "Started")
.Select(_ => new Unit());
});
}然后,您可以将其用作阻塞:
new Component().AsObservable().First();非阻塞:
new Component().AsObservable().Subscribe(_ => Console.WriteLine("Done"));热门:
var pub = new Component().AsObservable().Publish();
pub.Subscribe(_ => Console.WriteLine("Sub1"));
pub.Subscribe(_ => Console.WriteLine("Sub2"));
pub.Connect(); // started just once per two subscriptions可组合的:
new Component().AsObservable().Delay(TimeSpan.FromSeconds(1));等等。
编辑:对于必须等待和收集信息的多个事件的情况,可以使用以下变体:
public static IObservable<EventArgs> AsObservable(this Component component)
{
return Observable.Defer(() =>
{
component.BeginStart();
return
Observable.FromEvent<EventArgs>(component, "Started1").Take(1)
.Merge(
Observable.FromEvent<EventArgs>(component, "Started2").Take(1))
.Select(evt => evt.EventArgs);
});
}在这个例子中,如果你想阻塞直到完成,你可以使用.AsObservable.Last()。
发布于 2010-06-03 03:42:55
下面这样的代码应该可以做到:
var replay = Observable
.FromEvent<EventArgs>(this.component, "Started")
.Replay();
replay.Connect();
component.BeginStart();
replay.First();https://stackoverflow.com/questions/2956195
复制相似问题