【问题标题】:Subscribe to observable and await later订阅 observable 并稍后等待
【发布时间】:2018-11-26 23:34:33
【问题描述】:

以下不会捕获发出的值:

someObservable = Observable.FromEventPattern(this, "MyEvent");
FireMyEvent("foo");
await someObservable.FirstOrDefaultAsync(e => e.Args == "foo");

所以我在单元测试中遇到了这种模式:

var tsc = new TaskCompletionSource<bool>();

var callback = someObservable.FirstOrDefaultAsync(...);

using (callback.Subscribe(e => tsc.SetResult(e.Args)))
{
    FireMyEvent("foo");
    tsc.Task.Wait(1000);
}
Assert.AreEqual("foo", tsc.Task.Result);

基本上我需要订阅,然后触发操作,然后等待订阅的 observable。

是否可以在不引入新任务或 WaitHandle 的情况下简化此订阅/等待?

【问题讨论】:

    标签: c# system.reactive


    【解决方案1】:

    我不确定你到底想做什么,但如果我理解基本思想,那么这行得通:

    var subject = new Subject<Unit>();
    
    var callback = subject.FirstOrDefaultAsync();
    
    using (callback.Subscribe(_ => { }, () => Console.WriteLine("Done.")))
    {
        subject.OnNext(Unit.Default);
    }
    

    您能更全面地解释一下您的用例吗?

    【讨论】:

    • 是的,但我需要等到 FirstOrDefault() 返回值,否则我无法执行断言或任何逻辑。我的问题在于等待,而不是发出值
    【解决方案2】:
    1. 我不太明白您的假设,即 await 不会捕获结果。
    2. 您必须在事件被触发之前等待它

    someObservable = Observable.FromEventPattern(this, "MyEvent"); Task.Delay(1000).ContinueWith(_ => FireMyEvent("foo")); var result = await someObservable.FirstOrDefaultAsync(e => e.Args == "foo");

    您的结果现在是一个 EventPattern。不过我会推荐一个更安全的 FromEventPattern-Overload 类型:

    var eventObservable = Observable
                .FromEventPattern<YourEventArgs>(
                    h => MyEvent += h,
                    h => MyEvent -= h);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 2018-09-05
      • 2017-09-03
      相关资源
      最近更新 更多