Manejador de eventos vs Tema Rx
Estoy usando System.Reactive
y no sé cuál elegir: ¿EventHandlers o Subjects? ¿Cuál es la diferencia entre ellos?
var client = WebSocketClient.Create(uri);
// Subject
client.OnConnected
.Subscribe(_ => { Log.Information($”Socket {client.Id} connected”); })
.DisposeWith(disposable);
// EventHandler
Observable
.FromEventPattern(h => client.Connected += h, h => client.Connected -= h)
.Select(_ => Unit.Default)
.Subscribe(_ => { Log.Information($”Socket {client.Id} connected”); })
.DisposeWith(disposable);
“`cs
public class WebSocketClient : IWebSocketClient
{
// Subject
private readonly ISubject<unit> _connectedSubject = new Subject<unit>();
<pre><code>public IObservable<unit> OnConnected => _connectedSubject.AsObservable();
// EventHandler
private EventHandler? _connected;
public event EventHandler Connected
{
add => _connected += value;
remove => _connected -= value;
}
// Lógica
async Task IWebSocketClient.ConnectAsync(CancellationToken cancellationToken)
{
…
await _webSocket.ConnectAsync(_uri, cancellationToken).ConfigureAwait(false);
_connected?.Invoke(this, EventArgs.Empty);
_connectedSubject.OnNext();
…
}
private void Dispose()
{
_connectedSubject.OnCompleted();
}
</code></pre>
}
“`
davy.ai
La principal diferencia entre
EventHandlers
ySubjects
enSystem.Reactive
es que losEventHandlers
son una forma de convertir una API basada en eventos en una secuencia observable, mientras que losSubjects
son una forma de crear manualmente una secuencia observable y enviar datos a la misma.Observable.FromEventPattern
es un método de fábrica que toma dos expresiones lambda, una para suscribirse a un evento (client.Connected += h
) y otra para cancelar la suscripción (client.Connected -= h
), y devuelve una secuencia observable que produce objetosEventPattern<teventargs>
. Esto te permite suscribirte a un evento de manera reactiva y utilizar todos los operadores disponibles enSystem.Reactive
.Por otro lado, un
Subject
es un tipo que implementa tantoIObserver<t>
comoIObservable<t>
. Te permite enviar datos manualmente a través de él (usandoOnNext
) y suscribirte a él como lo harías con cualquier otra secuencia observable. En el fragmento de código,_connectedSubject
es un subject que se utiliza para enviar una sola unidad de datos (Unit.Default
) cada vez que se produce el eventoConnected
.En resumen, si estás trabajando con una API existente basada en eventos, puedes utilizar
Observable.FromEventPattern
para convertir los eventos en secuencias observables. Si necesitas crear manualmente una secuencia observable y enviar datos a la misma, puedes utilizar unSubject
.