Почему мне НЕ нужно публиковаться на этой холодной наблюдаемой? - PullRequest
2 голосов
/ 12 ноября 2011

Поскольку у меня простуда Observable здесь, и я подписываюсь на "сгруппированные" несколько раз, почему мне НЕ нужно публиковать здесь?Я ожидал бы, что это вызовет нежелательные результаты при запуске, но, к моему удивлению, это работает с и без публикации.Почему это так?

var subject = new List<string>
    {                            
    "test",                        
    "test",                 
    "hallo",
    "test",
    "hallo"
    }.ToObservable();
subject
    .GroupBy(x => x)
    .SelectMany(grouped => grouped.Scan(0, (count, _) => ++count)
         .Zip(grouped, (count, chars) => new { Chars = chars, Count = count }))
    .Subscribe(result => Console.WriteLine("You typed {0} {1} times", 
         result.Chars, result.Count));

// I Would have expect that I need to use Publish like that
//subject
//   .GroupBy(x => x)
//   .SelectMany(grouped => grouped.Publish(sharedGroup => 
//       sharedGroup.Scan(0, (count, _) => ++count)
//       .Zip(sharedGroup, (count, chars) => 
//           new { Chars = chars, Count = count })))
//   .Subscribe(result => Console.WriteLine("You typed {0} {1} times", 
//       result.Chars, result.Count));

Console.ReadLine();

РЕДАКТИРОВАТЬ

Как заметил Пол, поскольку мы подписываемся на базовую холодную наблюдаемую дважды, нам следует дважды повторить последовательность.Однако мне не повезло сделать этот эффект видимым.Я пытался вставить строки отладки, но, например, это печатает «выполнение» только один раз.

var subject = new List<Func<string>>
{                            
() =>
    {
        Console.WriteLine("performing");
        return "test";
    },                        
() => "test",                 
() => "hallo",
() => "test",
() => "hallo"
}.ToObservable();


subject
    .Select(x => x())
    .GroupBy(x => x)
    .SelectMany(grouped => grouped.Scan(0, (count, _) => ++count)
            .Zip(grouped, (count, chars) => new { Chars = chars, Count = count }))
    .Subscribe(result => Console.WriteLine("You typed {0} {1} times",
            result.Chars, result.Count));

Интересно, сможем ли мы сделать эффект видимым, что мы имеем дело с наблюдаемой холодом и не используем Publish(),В другом шаге я хотел бы увидеть, как Publish() (см. Выше) заставляет эффект исчезнуть.

РЕДАКТИРОВАТЬ 2

Как предположил Пол, я создал кастомIObservable<string> для отладки.Тем не менее, если вы установите точку останова в методе Subscribe(), вы заметите, что он просто нажмет один раз .

class Program
{
    static void Main(string[] args)
    {
        var subject = new MyObservable();

        subject
            .GroupBy(x => x)
            .SelectMany(grouped => grouped.Scan(0, (count, _) => ++count)
                 .Zip(grouped, (count, chars) => new { Chars = chars, Count = count }))
            .Subscribe(result => Console.WriteLine("You typed {0} {1} times",
                 result.Chars, result.Count));

       Console.ReadLine();
   }
}

class MyObservable : IObservable<string>
{
    public IDisposable Subscribe(IObserver<string> observer)
    {
        observer.OnNext("test");
        observer.OnNext("test");
        observer.OnNext("hallo");
        observer.OnNext("test");
        observer.OnNext("hallo");
        return Disposable.Empty;
    }
}

Так что для меня вопрос все еще открыт.Почему мне не нужно Publish здесь, в этот холодный Observable?

Ответы [ 2 ]

6 голосов
/ 16 ноября 2011

Вы используете свой источник на основе списка только один раз, поэтому вы не увидите там повторяющихся эффектов подписки.Ключом к ответу на ваш вопрос является следующее наблюдение:

IGroupedObservableобъект, вытекающий из GroupBy, сам по себе является скрытым субъектом.

Внутренне, GroupBy хранит словарь,Всякий раз, когда приходит сообщение, оно отправляется в тему с соответствующим ключом.Вы дважды подписываетесь на объект группировки, который является безопасным, поскольку субъект отделяет производителя от потребителя.

1 голос
/ 13 ноября 2011

Повторное использование 'grouped' в Zip означает, что вы эффективно делаете каждую группировку дважды - однако, поскольку ваш источник холодный, он все еще работает.Имеет ли это смысл?

...