Эта статья является зеркальной статьёй машинного перевода, пожалуйста, нажмите здесь, чтобы перейти к оригиналу.

Вид: 2585|Ответ: 2

[Источник] Изучайте темы в расширении .Net Reactive Responsive

[Скопировать ссылку]
Опубликовано 27.01.2024 12:17:19 | | | |
.Net Reactive Extension предоставляет разработчикам набор функций для реализации реактивной модели программирования для .Net, чтобы упростить и выразить обработку событий с помощью декларативных действий. Хотя ключевыми краеугольными камнями реактивного масштабирования являются интерфейсы IObserver и IObservable, разработчику часто не нужно реализовывать эти интерфейсы самостоятельно. Библиотека поддерживает встроенный тип Subject<T>, который реализует интерфейсы и поддерживает множество функций.

Темы лежат в основе различных тем, доступных в библиотеке, а также есть другие темы — <T>ReplaySubject,<T> BehaviorSubject и AsyncSubject<T>. Полезно понять основные различия между ними и то, как использовать их для лучшего использования библиотеки.

В этой статье мы сравним<T> Субъекта и его брата, пытаясь проиллюстрировать различия в их поведении.

Тема<T>

Как уже упоминалось, Subject<T> служит основой для доступных тем, предоставляя простой способ пользоваться библиотекой без самостоятельной реализации интерфейсов IObservable<T> и IObserver.<T> Простая демонстрация типа темы показана ниже.

В приведённом выше коде мы создали <T>экземпляр Subject, и поскольку он реализует<T> IObserver и IObserverable<T>, используем один и тот же экземпляр для подписки и публикации значения в IObserver. Ещё один важный момент — как мы используем перегрузку метода Subscribe для принятия действий в качестве входа. Это будет сделано для каждого опубликованного значения, в данном случае — печать числа на консоль.

Давайте попробуем показать опубликованные значения и значения, которые IObserver (в этом <T>действии) выводит на консоль на следующем изображении. Это поможет нам легко сравнивать оставшихся братьев и сестёр и вариантов.



Первая строка представляет опубликованное значение, а вторая — полученное IObserver. Кроме того, мы добавили строку, указывающую, в какой момент наблюдатель подписывается на поток во время выполнения. Эта линия представлена вертикальной пунктирной линией.

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

Но что если наблюдатель подписывается на данные только после того, как некоторые значения уже опубликованы? Влияет ли это на данные, получаемые наблюдателями? Прежде чем смотреть на результат, давайте сначала напишем тот же код.

В приведённом выше коде можно заметить, что наблюдатель подписывается на поток данных только после публикации двух значений (1 и 2). Как и следовало ожидать, это приведёт к тому, что наблюдатели не будут получать опубликованные данные до вызова метода подписки. Как показано на рисунке ниже.



А что если вы хотите прочитать все опубликованные ценности, даже если наблюдатель подписывается поздно? Вот тут<T> и вступает в игру ReplaySubject.

ReplayТема<T>

ReplaySubject<T> кэширует ценности и воспроизводит их для последующих подписчиков. Это полезно для избегания гоночных условий. Давайте изменим предыдущий код, чтобы использовать<T> ReplaySubject и посмотрим, как это влияет на то, что получает наблюдатель.

Как показано в приведённом выше коде, в коде<T> <T>почти нет изменений, кроме того, что теперь мы используем ReplaySubject вместо subject. Следующая диаграмма иллюстрирует влияние на данные, полученные наблюдателем.



Как показано на изображении, кэшированное значение теперь воспроизводится для абонента, даже если абонент подписывается позже. Конечно, эта полезная функция имеет свою цену. Эта реализация кэширует каждое значение, публикуемое подписчиком, что может вызвать проблемы с памятью при значительно большем объёме данных.

Однако у<T> ReplaySubject есть несколько способов решить эту проблему. Для этого примера мы рассмотрим два примера, которые используют ограничения по размеру и времени для ограничения кэшируемого значения.

В первом случае мы используем размер кэша для ограничения его значения. <T>Конструктор ReplaySubject предоставляет перегрузку, которая принимает целое число, отражающее размер буфера кэша (максимальное количество элементов). В нашем примере изменим код, чтобы ограничить размер кэша до 1.

Обратите внимание, как мы используем <T>перегрузку конструкторов ReplaySubject, чтобы обозначает размер кэша как 1. Это ограничивает кэширование и гарантирует, что только один элемент кэшируется и заменяется новым сразу после публикации. Влияние изменений показано ниже.



Другой способ ограничить кэширование — ограничить время кэшированного элемента, то есть обеспечить срок действия для кэшированного элемента.

Давайте напишем код, чтобы проиллюстрировать этот пример.

Аналогично предыдущему коду, мы используем<T> перегрузку конструктора ReplaySubject для указания срока истечения предметов в кэше. Чтобы продемонстрировать нашу ситуацию, мы ввели задержку между выпуском значений.

Поскольку для подписки наблюдателя требуется целых 1200 мс, любые элементы, превышающие срок действия в 1000 мс, будут удалены из кэша. В этом примере это приведёт к удалению значения 1 из кэша и не будет воспроизведено для поздних подписчиков. Как показано на рисунке ниже.



Есть <T>и другие перегрузки ReplaySubject, которые дают больше гибкости и тонко настраивают кэшированные значения, но, например, мы оставим уже упомянутые два примера.

ПоведениеТема<T>

BehaviourSubject <T>очень похож на<T> ReplaySubject тем, что помогает кэшировать значения. Но есть существенная разница. BehaviourSubject<T> кэширует только последнее опубликованное значение. Прежде чем перейти к этому дальше, давайте напишем немного кода.

Если BehaviorSubject<T> кэширует только одно значение (последнее известное), чем он отличается от ReplaySubject размера 1<T>? Следующая диаграмма чётко отражает ситуацию приведённого выше кода.



Однако это не совсем так. Здесь есть два важных различия, которые нужно понять. Первая — наличие дефолтов. Обратите внимание, что в приведённом выше <T>коде мы указываем значение 0 по умолчанию в конструкторе BehaviourSubject. Если в кэше нет значения (или, другими словами, данные не были опубликованы до подписки наблюдателя), значение по умолчанию возвращается. Это отличается от ReplaySubject, у которого размер 1<T>, и это не имеет значения. Следующий код и визуальное представление последовательности демонстрируют это поведение.



Второе отличие — это поведение<T> BehaviorSubject и<T> ReplaySubject при подписке на завершённую последовательность. После подписания BehaviorSubject <T> не будет иметь значения, как указано в коде ниже.

Подписчики гарантированно не получат никакой ценности, поскольку подписка оформляется после завершения.



Однако <T>это относится к ReplaySubject. Нет гарантии, что наблюдатель не получит значения, как показано в коде ниже.

Как показано в приведённом выше коде, кэш имеет размер 1, и даже если подписка будет вызвана после завершения вызова, кэш останется (до выполнения условия истечения), поэтому в этом случае будет получено последнее опубликованное значение.



AsyncSubject<T>

<T>AsyncSubject — это последний родственник Субъекта, который мы рассмотрим в этой статье<T>, и он очень похож на предыдущие два (ReplaySubject и BehaviorSubject) тем, что также кэширует результаты. Но опять же, есть существенная разница. AsyncSubject публикует последнее кэшированное значение только если последовательность помечена как <T> завершённая (кэширует только одно значение — последнее значение).

Рассмотрим следующий код.

Это создаст для наблюдателя значение, что последовательность отмечена как последнее опубликованное перед завершением — значение 4. Как показано на рисунке ниже.



Но что произойдёт, если пропустить вызов, который отмечает последовательность как завершённую? Давайте прокомментируем из строки и попробуем снова.

Это не генерирует никаких данных для наблюдателя, поскольку AsyncSubject<T> публикует результаты только после того, как последовательность отмечена как полная.



Это значительное отличие, которое должен учитывать любой, кто использует AsyncSubject<T>.

заключение

В этой статье <T>демонстрируются различия между различными братьями и сестрами Subject и некоторые его вариации. Часто полезно осознавать эти тонкие различия, так как они могут проявлять иначе, чем вы ожидали, если вы этого не осознаёте.

Оригинальная ссылка:Вход по гиперссылке виден.





Предыдущий:.NET/C# проверяет, доступен ли TCP-порт
Следующий:NSIS (1) Сделайте простой установщик
 Хозяин| Опубликовано 27.01.2024 12:19:47 |
Подписка на тематические темы для Angular RxJS
https://www.itsvse.com/thread-9209-1-1.html
 Хозяин| Опубликовано 28.04.2024 11:36:59 |
ASP.NET Core использует промежуточную модель MediatR
https://www.itsvse.com/thread-9272-1-1.html
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com