Ответ PL , если он идеально подходит для вашей спецификации, но я подумал, что вы могли бы добиться лучших результатов, не сражаясь с RX с .First (), а используя его, создавая наблюдаемый для вашего компонента:
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()
.