Mar*_*age 7 .net c# system.reactive
我想充分利用Reactive Extensions for .NET(Rx),并希望得到一些关于做一些基本任务的意见.为了说明我正在尝试做什么,我有一个人为的例子,我有一个带有异步事件的外部组件:
class Component {
public void BeginStart() { ... }
public event EventHandler Started;
}
Run Code Online (Sandbox Code Playgroud)
该组件通过调用启动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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想摆脱它ManualResetEvent,我希望Rx有一个解决方案.但是怎么样?
Ser*_*hov 10
PL的答案如果完全符合你的规范,但我认为你可以通过不与RX对战来获得更好的结果.First()但是通过为你的组件创建一个observable来接受它:
public static IObservable<Unit> AsObservable(this Component component)
{
return Observable.Defer(() =>
{
component.BeginStart();
return Observable
.FromEvent<EventArgs>(component, "Started")
.Select(_ => new Unit());
});
}
Run Code Online (Sandbox Code Playgroud)
然后你可以用它作为阻塞:
new Component().AsObservable().First();
Run Code Online (Sandbox Code Playgroud)
非阻塞:
new Component().AsObservable().Subscribe(_ => Console.WriteLine("Done"));
Run Code Online (Sandbox Code Playgroud)
热:
var pub = new Component().AsObservable().Publish();
pub.Subscribe(_ => Console.WriteLine("Sub1"));
pub.Subscribe(_ => Console.WriteLine("Sub2"));
pub.Connect(); // started just once per two subscriptions
Run Code Online (Sandbox Code Playgroud)
可组合:
new Component().AsObservable().Delay(TimeSpan.FromSeconds(1));
Run Code Online (Sandbox Code Playgroud)
等等...
编辑:对于您必须等待并收集信息的多个事件的情况,可以使用以下变体:
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);
});
}
Run Code Online (Sandbox Code Playgroud)
有了这个,如果你想阻止直到完成,你可以使用.AsObservable.Last().
| 归档时间: |
|
| 查看次数: |
6540 次 |
| 最近记录: |