gpt4 book ai didi

.net - 观察添加到 RX 列表中的项目

转载 作者:行者123 更新时间:2023-12-04 00:47:09 24 4
gpt4 key购买 nike

我试图让一个简单的演示工作。

我有一个字符串集合,我想在不使用任何控制事件代码的情况下观察它的添加。不知何故,我得到的印象可能是错误的,即 Rx 或 .Net 的其他部分支持这一点,而没有求助于连接所有各种事件(可能会或可能不会)将成员添加到集合中。

如果我更换我的 source有一个间隔,就像在注释掉的代码中一样,委托(delegate)被调用 (ala, var source = Observable.Interval(TimeSpan.FromSeconds(1)); 。这让我希望我可以在这里做我想做的事情,也许是错误的。

基本示例来自 Creating and Subscribing to Simple Observable Sequences

在下面的代码中,我想做的是观察 source直接收集(而不是通过控制事件)并在将项目添加到集合时调用委托(delegate)。

如果他们确实支持我的论点,即他们支持此功能,我宁愿不绕过 LINQ 或 RX。

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;

public class frmRx
{

ObservableCollection<string> ObservableCollection = new ObservableCollection<string>();
Dim source = Observable.ToObservable(ObservableCollection).ObserveOn(SynchronizationContext.Current)

//this code worked, but it's not a collection I made
//source = Observable.Interval(TimeSpan.FromSeconds(1)).Select(x => x.ToString).ObserveOn(SynchronizationContext.Current);

private void frmRx_Load(System.Object sender, System.EventArgs e)
{
IConnectableObservable<string> Publication = Observable.Publish<string>(source);
Publication.Subscribe(x => { AddToTreeView(x); }, ex => { }, () => { });
Publication.Connect();
}

private void AddToTreeView(string Text)
{
TreeView1.Nodes.Add(Text); //this never gets called
}

// this is just my test way of adding a member to the collection.
// but the adding could happen anywhere,
// and I want to watch the collection changes regardless of how it came about
private void TextBox1_TextChanged(System.Object sender, System.EventArgs e)
{
ObservableCollection.Add(TextBox1.Text.Last);
}
public frmRx()
{
Load += frmRx_Load;
TextBox1.TextChanged += TextBox1_TextChanged;
}
}

最佳答案

你犯了Observable.ToObservable(ObservableCollection)的错误。将创建一个 IObservable<string>这将为 ObservableCollection 的 future 更新生成值.

它不是。
.ToObservable(...)扩展方法只是将 IEnumerable<>进入和IObservable<>以便在订阅 observable 的那一刻枚举值。

您需要使用 Subject<string>如果您希望将新值推送给您的订阅者。

除此之外,您的代码并非尽可能简单。你为什么要发布 observables?

这是您可以编写的最简单的代码以使其工作:

public class frmRx
{
private Subject<string> source = new Subject<string>();

public frmRx()
{
source.ObserveOn(this).Subscribe(x => TreeView1.Nodes.Add(x));
TextBox1.TextChanged += (s, e) => source.OnNext(TextBox1.Text);
}
}

我已经包含了 .ObserveOn(this)因为将它们放入是一个好习惯,但在这种情况下不需要它。

我更希望看到的是:
public class frmRx
{
public frmRx()
{
Observable
.FromEventPattern(
h => textBox1.TextChanged += h,
h => textBox1.TextChanged -= h)
.Select(x => textBox1.Text)
.Subscribe(x => treeView1.Nodes.Add(x));
}
}

这避免了主题,并且在强类型化时尽可能简单。

最好更进一步,更好地清理关闭时的订阅,如下所示:
        var subscription =
Observable
.FromEventPattern(
h => textBox1.TextChanged += h,
h => textBox1.TextChanged -= h)
.Select(x => textBox1.Text)
.Subscribe(x => treeView1.Nodes.Add(x));

this.FormClosing += (s, e) => subscription.Dispose();

关于.net - 观察添加到 RX 列表中的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28270069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com