C# 如何观察无功扩展(Rx)中的相关事件?

C# 如何观察无功扩展(Rx)中的相关事件?,c#,system.reactive,C#,System.reactive,处理相关事件的最佳方法是什么,例如: 我需要测试一个对象的连接是否成功或失败。 但该对象首先需要通过初始化步骤,我测试该步骤是否成功,然后继续连接步骤 如果初始化失败,则返回连接失败 如果初始化成功,则返回连接步骤的结果 我的代码如下。有没有更好的方法来处理这些依赖事件,因为我订阅的是初始化订阅中的连接 如果我有更多像这样的依赖事件,我会继续嵌套订阅吗 public static void Test() { const int maxValue = 501; var ran

处理相关事件的最佳方法是什么,例如:
我需要测试一个对象的连接是否成功或失败。 但该对象首先需要通过初始化步骤,我测试该步骤是否成功,然后继续连接步骤

  • 如果初始化失败,则返回连接失败
  • 如果初始化成功,则返回连接步骤的结果
我的代码如下。有没有更好的方法来处理这些依赖事件,因为我订阅的是初始化订阅中的连接

如果我有更多像这样的依赖事件,我会继续嵌套订阅吗

public static void Test()
{
    const int maxValue = 501;

    var random = new Random(BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0));

    var initOk = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => true);
    var initKo = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => false);

    var connectOk = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => true);
    var connectKo = Observable.Interval(TimeSpan.FromMilliseconds(random.Next(maxValue))).Select(i => false);

    var initResult = initOk.Amb(initKo).Take(1);
    var connectResult = connectOk.Amb(connectKo).Take(1);

    var id =
        initResult.Subscribe(ir =>
                                 {
                                     if (ir)
                                     {
                                         var cd =
                                             connectResult.Subscribe(cr =>
                                                                         {
                                                                             Console.WriteLine(cr
                                                                                                   ? "Connection succeeded."
                                                                                                   : "Connection failed.");
                                                                         });
                                     }
                                     else
                                     {
                                         Console.WriteLine("Initialization failed thus connection failed.");
                                     }
                                 });
}

通常,您可以通过使用各种rx运营商来连锁调用来避免嵌套

您的示例可以通过以下方式进行整理:

initResult.SelectMany(ir =>
       {   
           if (ir != null)
           {
             return connectResult;
           }

           Console.WriteLine("Initialization failed thus connection failed.");

           return Observable.Throw(new Exception("Some Exception"));
       })
       .Subscribe(cr =>
           {
              Console.WriteLine(cr != null
                 ? "Connection succeeded." 
                 : "Connection failed.");
           })
你可以用这个:

var finalResult =
    initResult
        .Select(ir =>
            Observable.If(() => ir, connectResult, Observable.Return(false)))
        .Merge();
要发布消息,您可以如下更改:

var initResultText =
    initResult
        .Select(ir =>
            ir ? (string)null : "Initialization failed thus connection failed.");

var connectResultText =
    connectResult
        .Select(cr => 
            String.Format("Connection {0}.", cr ? "succeeded" : "failed"));

var finalResult =
    initResultText
        .Select(irt =>
            Observable.If(() =>
                irt == null, connectResultText, Observable.Return(irt)))
        .Merge();

如果你需要比这更深入的话,你应该考虑做一个扩展复杂性的扩展方法,这样合成就容易多了。我更喜欢在我的场景中更灵活的SelectMany方法。但你的方法也很可爱。