使用反应式扩展以正确的顺序处理多个响应

2023-12-27

情况

我有一个系统,其中一个请求会产生两个响应。请求和响应有相应的可观察量:

IObservable<RequestSent> _requests;
IObservable<MainResponseReceived> _mainResponses;
IObservable<SecondResponseReceived> _secondaryResponses;

可以保证RequestSent事件发生早于MainResponseReceived and SecondaryResponseReceived但响应的顺序是随机的。

我拥有的

最初我想要处理这两个响应的处理程序,所以我压缩了可观察量:

_requests
    .SelectMany(async request =>
    {
        var main = _mainResponses.FirstAsync(m => m.Id == request.Id);
        var secondary = _secondaryResponses.FirstAsync(s => s.Id == request.Id);

        var zippedResponse = main.Zip(secondary, (m, s) => new MainAndSecondaryResponseReceived {
            Request = request,
            Main = m, 
            Secondary = s
        });
        return await zippedResponse.FirstAsync(); ;
    })
    .Subscribe(OnMainAndSecondaryResponseReceived);

我需要的

现在我还需要处理MainResponseReceived无需等待 secondaryResponseRecieved,并且必须保证 OnMainResponseRecieved 在之前完成OnMainAndSecondaryResponseReceived叫做

请问这两个订阅如何定义?

测试用例1:

  1. RequestSent occurs
  2. MainResponseReceived发生 -> OnMainResponseReceived 被调用
  3. SecondaryResponseReceived 发生 -> OnMainAndSecondaryResponseReceived 被调用

测试案例2:

  1. RequestSent occurs
  2. SecondaryResponseReceived occurs
  3. MainResponseReceived occurs-> OnMai ResponseReceived 被调用 -> OnMainAnd secondary ResponseReceived 被调用

我认为你几乎走在正确的轨道上。我不会再摆弄所有异步的东西 - 这只会让事情变得复杂。

尝试这个查询:

var query =
    _requests
        .SelectMany(request =>
            _mainResponses.Where(m => m.Id == request.Id).Take(1)
                .Do(m => OnMainResponseReceived(m))
                .Zip(
                    _secondaryResponses.Where(s => s.Id == request.Id).Take(1),
                    (m, s) => new MainAndSecondaryResponseReceived()
                    {
                        Request = request,
                        Main = m, 
                        Secondary = s
                    }));

var subscription =
    query.Subscribe(x => OnMainAndSecondaryResponseReceived(x));

The .Do(...)是代码中重要的缺失部分。它确保OnMainResponseReceived之前被调用OnMainAndSecondaryResponseReceived无论主要响应还是次要响应先出现。

我对此进行了测试:

Subject<RequestSent> _requestsSubject = new Subject<RequestSent>();
Subject<MainResponseReceived> _mainResponsesSubject = new Subject<MainResponseReceived>();
Subject<SecondResponseReceived> _secondaryResponsesSubject = new Subject<SecondResponseReceived>();

IObservable<RequestSent> _requests = _requestsSubject.AsObservable();
IObservable<MainResponseReceived> _mainResponses = _mainResponsesSubject.AsObservable();
IObservable<SecondResponseReceived> _secondaryResponses = _secondaryResponsesSubject.AsObservable();

_requestsSubject.OnNext(new RequestSent() { Id = 42 });
_mainResponsesSubject.OnNext(new MainResponseReceived() { Id = 42 });
_secondaryResponsesSubject.OnNext(new SecondResponseReceived() { Id = 42 });

_requestsSubject.OnNext(new RequestSent() { Id = 99 });
_mainResponsesSubject.OnNext(new MainResponseReceived() { Id = 99 });
_secondaryResponsesSubject.OnNext(new SecondResponseReceived() { Id = 99 });
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用反应式扩展以正确的顺序处理多个响应 的相关文章

  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • strlen() 编译时优化

    前几天我发现你可以找到编译时strlen使用这样的东西 template
  • 如何在 C# 中将 Json 转换为对象

    我想将 Json 转换为 C 中的对象 这里的 Json 是 值 e920ce0f e3f5 4c6f 8e3d d2fbc51990e4 如何使用 Object 问题看似愚蠢 但其实并不那么愚蠢 我没有简单的 Json 我有 IEnume
  • 2个对象,完全相同(除了命名空间)c#

    我正在使用第三方的一组网络服务 但遇到了一个小障碍 在我手动创建将每个属性从源复制到目标的方法之前 我想我应该在这里寻求更好的解决方案 我有 2 个对象 一个是 Customer CustomerParty 类型 另一个是 Appointm
  • 使用 C# 和 ASP.NET 在电子邮件附件中发送 SQL 报告

    我正在尝试使用 ASP NET 和 C 从 sql reportserver 2008 作为电子邮件附件发送报告 到目前为止我学会了如何获取 PDF 格式的报告 http weblogs asp net srkirkland archive
  • 防止控制台应用程序中的内存工作集最小化?

    我想防止控制台应用程序中的内存工作集最小化 在Windows应用程序中 我可以这样做覆盖 SC MINIMIZE 消息 http support microsoft com kb 293215 en us fr 1 但是 如何在控制台应用程
  • MVC 5 中具有 ASP.NET Identity 的 Autofac 不会验证 OWIN 管道中的安全标记

    我在 MVC 5 中设置了 AutoFac 来与 ASP NET Identity 一起使用 表面上一切似乎都工作正常 即用户可以创建帐户并登录 但后来我发现 当安全标记更改时 用户不会注销 通过在 AspNetUsers 表中进行暴力破解
  • 用于在标头更改时重新编译的简单 C 项目的示例 makefile

    有谁有完整的 makefile 可以执行以下操作 如果 HEADER 文件发生更改 则重建项目 cpp 文件在 makefile 中列出 头文件未在 makefile 中列出 头文件允许与 cpp 文件具有不同的名称 部分cpp文件没有头文
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • 如何在多线程应用程序中安全地填充数据并 Refresh() DataGridView?

    我的应用程序有一个 DataGridView 对象和一个 MousePos 类型的列表 MousePos 是一个自定义类 它保存鼠标 X Y 坐标 类型为 Point 和该位置的运行计数 我有一个线程 System Timers Timer
  • 如何从 Boost.PropertyTree 复制子树

    我有一些boost property tree ptree 我需要树来删除一些具有特定标签名称的元素 例如 xml 表示源ptree如下
  • MySQL 连接器 C++ 64 位在 Visual Studio 2012 中从源代码构建

    我正在尝试建立mySQL 连接器 C 从源头在视觉工作室2012为了64 bit建筑学 我知道这取决于一些boost头文件和C 连接器 跑步CMake生成一个项目文件 但该项目文件无法编译 因为有一大堆非常令人困惑的错误 这些错误可能与包含
  • ASP.NET Core 中间件与过滤器

    在阅读了 ASP NET Core 中间件之后 我对何时应该使用过滤器以及何时应该使用中间件感到困惑 因为它们似乎实现了相同的目标 什么时候应该使用中间件而不是过滤器 9频道有一个关于此的视频 ASP NET 怪物 91 中间件与过滤器 h
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • 调用 .ToArray() 时出现 ArgumentException

    我有一个经常被清除的列表 代码完全是这样的 VisitorAgent toPersist List
  • 如何组合两个 lambda [重复]

    这个问题在这里已经有答案了 可能的重复 在 C 中组合两个 lambda 表达式 https stackoverflow com questions 1717444 combining two lamba expressions in c
  • ContentDialog Windows 10 Mobile XAML - 全屏 - 填充

    我在项目中放置了一个 ContentDialog 用于 Windows 10 上的登录弹出窗口 当我在移动设备上运行此项目时 ContentDialog 未全屏显示 并且该元素周围有最小的填充 在键盘上可见 例如在焦点元素文本框上 键盘和内
  • 如何为有时异步的操作创建和实现接口

    假设我有数百个类 它们使用 计算 方法实现公共接口 一些类将执行异步 例如读取文件 而实现相同接口的其他类将执行同步代码 例如将两个数字相加 为了维护和性能 对此进行编码的好方法是什么 到目前为止我读到的帖子总是建议将异步 等待方法冒泡给调
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐