创建对 IObservable 的弱订阅

2023-12-30

我想要做的是确保如果对我的观察者的唯一引用是可观察的,它会被垃圾收集并停止接收消息。

假设我有一个带有列表框的控件,称为“消息”,后面的代码如下:

//Short lived display of messages (only while the user's viewing incoming messages)
public partial class MessageDisplay : UserControl
{
    public MessageDisplay()
    {
        InitializeComponent();
        MySource.IncomingMessages.Subscribe(m => Messages.Items.Add(m));
    }
}

哪个连接到这个源:

//Long lived location for message store
static class MySource
{
    public readonly static IObservable<string> IncomingMessages = new ReplaySubject<string>;
}

我不希望消息显示在不再可见后很长时间内仍保留在内存中。理想情况下,我想要一点扩展,这样我就可以写:

MySource.IncomingMessages.ToWeakObservable().Subscribe(m => Messages.Items.Add(m));

我也不想依赖 MessageDisplay 是一个用户控件这一事实,因为我稍后会想要使用 MessageDisplayViewModel 进行 MVVM 设置,而这不会是一个用户控件。


您可以将代理观察者订阅到可观察对象,该可观察对象持有对实际观察者的弱引用,并在实际观察者不再活动时处置订阅:

static IDisposable WeakSubscribe<T>(
    this IObservable<T> observable, IObserver<T> observer)
{
    return new WeakSubscription<T>(observable, observer);
}

class WeakSubscription<T> : IDisposable, IObserver<T>
{
    private readonly WeakReference reference;
    private readonly IDisposable subscription;
    private bool disposed;

    public WeakSubscription(IObservable<T> observable, IObserver<T> observer)
    {
        this.reference = new WeakReference(observer);
        this.subscription = observable.Subscribe(this);
    }

    void IObserver<T>.OnCompleted()
    {
        var observer = (IObserver<T>)this.reference.Target;
        if (observer != null) observer.OnCompleted();
        else this.Dispose();
    }

    void IObserver<T>.OnError(Exception error)
    {
        var observer = (IObserver<T>)this.reference.Target;
        if (observer != null) observer.OnError(error);
        else this.Dispose();
    }

    void IObserver<T>.OnNext(T value)
    {
        var observer = (IObserver<T>)this.reference.Target;
        if (observer != null) observer.OnNext(value);
        else this.Dispose();
    }

    public void Dispose()
    {
        if (!this.disposed)
        {
            this.disposed = true;
            this.subscription.Dispose();
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建对 IObservable 的弱订阅 的相关文章

随机推荐

  • localStorage不存储多于一份数据

    我正在尝试在 localStorage 中存储多条数据 然而 只存储了一件 我不明白为什么 这是代码 div div div div
  • C++试图理解顺时针规则来破译复杂的语法

    我有以下代码 int ia 3 4 0 1 2 3 4 5 6 7 8 9 10 11 int p4 4 ia cout lt lt p4 0 3 lt lt p4 0 3 lt lt endl cout lt lt p4 0 3 lt l
  • Cypress.io + TypeScript。测试开始时断言调用

    我是 Cypress io 和 TypeScript 的新手 所以我不明白这里的一些东西 My code Test describe TEST description function it newJobCreation function
  • Azure 认知搜索文本翻译技能 50k 字符限制

    我们正在使用 Azure 认知搜索来索引各种文档 例如Word 或 PDF 文件 存储在 Azure Blob 存储中 我们希望能够翻译提取的非英语文档内容 并将翻译结果存储到索引中的专用字段中 目前 内置的文本翻译认知技能最多支持输入 5
  • 用perl分割一个带有多个空格的字符串?

    我正在尝试用多个空格分割一个字符串 我只想在有 2 个或更多空白的地方进行分割 我尝试了多种方法 但一直得到相同的输出 即它在每个字母后都会分裂 这是我尝试的最后一件事 cellMessage split s 2 g message for
  • Java 中的多重继承是如何工作的? [复制]

    这个问题在这里已经有答案了 Class Object是类层次结构的根 每个班级都有Object作为一个超类 那么 如果我扩展一个 API 类 它会像多重继承吗 显然 Java不支持多重继承 那么它是如何运作的呢 超类与父类不同 你只能有一位
  • 从非 ssl 端口 8080 重定向到 ssl 端口 8443

    我试图将非 SSL 端口 8080 上的流量重定向到 SSL 端口 8443 在 Jboss 4 2 3 GA 版本上 但它不起作用 当我在此端口上访问我的网络应用程序时 它会保留在该端口上并显示页面 这是我在 server xml 文件中
  • Java 文本文件大小(文件关闭前)

    我正在从一项服务收集完整的 HTML 该服务提供对大量博客和新闻网站的访问 我正在检查 HTML 实时 看看它是否包含一些关键字 如果它包含其中一个关键字 我会将 HTML 写入文本文件来存储它 我想这样做一个星期 因此我正在收集大量数据
  • 如果使用优化(-O2、-O3),为什么此代码的行为会有所不同?

    我必须编写一些检查例程 如果使用 O0 O1 O2 或 O3 它们的行为似乎会有所不同 下面我创建了一个适用于 O0 和 O1 的最小示例 但使用 O2 或 O3 行为发生了变化 在 O0 和 O1 情况下 for 循环递增整数 并且第一次
  • 通过单击 swift 中的 TableView 单元格转到 ViewController

    有一个类MenuViewController 其中记录了表中记录的数组 import Foundation import UIKit class MenuViewController UIViewController UITableView
  • 如何在 Woocommerce 中将“添加到购物车”文本更改为我自己的文本

    我在最新版本的 WordPress 中使用 Woocommerce V2 1 2 我用谷歌搜索过 他们给出了前端更改的解决方案 但我需要从后端进行更改 请提出解决上述问题的任何想法 这将会改变Add to cartwoocommerce 中
  • Visual Studio 代码 + MSTEST?

    有没有办法从 Visual Studio Code 运行和调试 MSTest V2 我很困惑 它从命令行运行得很好 dotnet test产生预期结果 这是我当前的 launch json 的样子 configurations name N
  • 将 .crt 文件转换为 .cer 和 .key

    我被要求帮助转换证书以进行续订 我获得了domainname crt 文件以及一些中间 crt 文件 但没有 key 文件 他们希望我将 CRT 转换为 CER 和 KEY 文件 我查看了以下内容 以及许多其他网站 但他们要么说我需要 ke
  • 在包“android”中找不到属性“showAsAction”的资源标识符

    正如标题所示 我在至少 3 个 XML 布局文件中遇到了该错误 但是 我在任何这些 XML 文件中都没有看到属性 showsAsAction 我是否错过了某些内容 或者我只是盲目的 是有问题的 XML 文件
  • Android 4.3:如何检查用户是否启用了锁定?

    如果用户没有锁定屏幕或仅启用了滑动功能 我希望我的应用程序表现不同 不存储内容 最高答案在这里 检查是否启用了锁定 https stackoverflow com questions 7768879 check whether lock w
  • 在 Mac 上安装 GNU GCC

    我最近对 Xcode 5 中包含的新 clang 编译器感到沮丧 我想知道在 OS X 上安装 GNU GCC 的最佳方法是什么 需要考虑的事项 我不想使用 MacPorts fink homebrew 或任何其他第三方包管理器 如果可能的
  • 从 HTML 表单发布 blob 的表单输入类型是什么?

    我想将录制的视频 保存为 blob 包含到将要发布的表单中 两个问题 发布 blob 所需的输入类型是什么 如何将 blob 分配给该输入类型 我所看到的一些内容建议使用文件的输入类型 表格示例
  • 如果任何列与一组值之一匹配,则保留行

    我有一个关于使用 R 进行子集化的简单问题 我想我已经很接近了 但还不太明白 基本上 我有 25 个感兴趣的列和大约 100 个值 我想保留其中一列中具有任何这些值的任何行 简单的例子 Values lt c 1 2 5 col1 lt c
  • AngularJS - 在 Angular 中声明服务的不同方式的主要区别是什么?

    我正在开发一个 AngularJS 应用程序 并试图坚持 AngularJs 中最有效和最广泛接受的开发风格 目前 我正在使用这种方式声明我的服务 如下所示 app factory MyService function function d
  • 创建对 IObservable 的弱订阅

    我想要做的是确保如果对我的观察者的唯一引用是可观察的 它会被垃圾收集并停止接收消息 假设我有一个带有列表框的控件 称为 消息 后面的代码如下 Short lived display of messages only while the us