为什么 IObservable.First() 会阻塞?

发布于 2024-11-28 01:25:09 字数 911 浏览 1 评论 0原文

我最近一直在尝试了解 .NET 的响应式扩展,但遇到了一些概念上的障碍:我无法弄清楚为什么 IObservable.First() 会阻塞。

我有一些示例代码,看起来有点像这样:

var a = new ListItem(a);
var b = new ListItem(b);
var c = new ListItem(c);
var d = new ListItem(d);

var observableList = new List<ListItem> { a,b,c,d }.ToObservable();

var itemA = observableList.First();

// Never reached
Assert.AreEqual(expectedFoo, itemA.Foo);

我期望发生的是 itemA 引用等于 a 并能够访问其成员,相反,发生的情况是 First() 阻塞,并且永远不会到达 Assert.AreEqual()

现在,我已经足够了解,当使用 Rx 时,代码应该 Subscribe()IObservable,所以很可能我在这里做了错误的事情。但是,根据各种方法签名,不可能执行以下任一操作:

observableList.First().Subscribe(item => Assert.AreEqual(expectedFoo, item));

observableList.Subscribe(SomeMethod).First() // This doesn't even make sense, right?

我缺少什么?

I've been trying to get my head around the Reactive Extensions for .NET of late, but have hit a bit of a conceptual wall: I can't work out why IObservable.First() blocks.

I have some sample code that looks a bit like this:

var a = new ListItem(a);
var b = new ListItem(b);
var c = new ListItem(c);
var d = new ListItem(d);

var observableList = new List<ListItem> { a,b,c,d }.ToObservable();

var itemA = observableList.First();

// Never reached
Assert.AreEqual(expectedFoo, itemA.Foo);

What I was expecting to happen was for itemA to be referentially equal to a and to be able to access its members, etc. What happens instead is that First() blocks and the Assert.AreEqual() is never reached.

Now, I know enough to know that when using Rx, code should Subscribe() to IObservables, so it's likely that I've just done the wrong thing here. However, it's not possible, based on the various method signatures to do either of:

observableList.First().Subscribe(item => Assert.AreEqual(expectedFoo, item));

or

observableList.Subscribe(SomeMethod).First() // This doesn't even make sense, right?

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

杀手六號 2024-12-05 01:25:09

在测试项目中尝试这段代码效果很好,所以我重新审视了有问题的代码。事实证明,问题是因为 IObservable 正在幕后某处进行 Publish() 编辑,因此被转换为 IConnectableObservable< /代码>。如果没有调用连接,订阅就永远不会“激活”。

Trying this code out in a test project worked fine, so I revisited the problematic code. It turned out the problem was because the IObservable<ListItem> was being Publish()ed somewhere under the covers and so being converted into an IConnectableObservable<ListItem>. Without a call to connect, the subscription was never "activated".

柠栀 2024-12-05 01:25:09

First() 返回一个 T,而不是 Observable,因此它必须阻塞。

非阻塞形式是 xs.Take(1)

First() returns a T, not an Observable<T>, so it must block.

A non-blocking form is xs.Take(1)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文