C# Rx Observable.Never <> ведет себя как Observable.Empty <>? - PullRequest
0 голосов
/ 07 марта 2020

Я новичок в Rx, и у меня есть этот фрагмент кода для попытки.

Observable.Never<string>().Subscribe(Console.Write);
Observable.Empty<string>().Subscribe(Console.Write);

Я ожидал, что Never<string>() будет вести себя как Console.ReadKey, что не закончится, но, как я запускаю эти 2 строки, они заканчиваются немедленно, поэтому [Никогда] ведет себя как [Пусто] для меня.

Какое правильное понимание [Никогда] и есть ли хороший пример использования для него?

Ответы [ 3 ]

3 голосов
/ 07 марта 2020

Наблюдаемые значения Observable.Never() и Observable.Empty() не будут выдавать никаких значений. Однако наблюдаемая, построенная с Observable.Never(), не будет завершена и вместо этого останется «открытой / активной». Может быть разница в том месте, где вы потребляете эти наблюдаемые, если наблюдаемое завершается (Empty()) или нет (Never()), но это зависит от вашего фактического варианта использования.

Наличие наблюдаемых, которые не Никакие значения не могут показаться бесполезными, но, возможно, вы находитесь в месте, где вы должны предоставить наблюдаемое (вместо использования null). Таким образом, вы можете написать что-то вроде этого:

public override IObservable<string> NameChanged => Observable.Never<string>();
2 голосов
/ 07 марта 2020

Так что у меня нет опыта работы с Rx, но я верю, что все, что Subscribe делает, это регистрирует, что делать, когда излучение наблюдается. Если ваша наблюдаемая никогда не излучает (ie Empty или Never), тогда метод никогда не вызывается. Приложение не ждет окончания самой подписки. Если вы хотите ждать вечно, вы должны использовать что-то вроде

Observable.Never<string>().Wait();

Это связано с тем, что вам не следует использовать асинхронную операцию c в Subscribe. Возьмите следующий код

static void Main(string[] args)
{
  Observable.Range(1, 5).Subscribe(async x => await DoTheThing(x));
  Console.WriteLine("done");
}

static async Task DoTheThing(int x)
{
  await Task.Delay(TimeSpan.FromSeconds(x));
  Console.WriteLine(x);
}

При запуске приложение сразу напишет «выполнено» и выйдет после помещения значений в наблюдаемое, потому что оно не знает о подписчике в контексте того, завершило ли оно свою обработку или не. Надеюсь, я ясно дал понять, и если кто-то с большим знанием Rx захочет вмешаться, если потребуется, это будет хорошо.

0 голосов
/ 07 марта 2020

Эта ссылка дает вам разницу между пусто , никогда и throw : http://reactivex.io/documentation/operators/empty-never-throw.html И это одно использование Никогда : https://rxjs-dev.firebaseapp.com/api/index/const/NEVER

...