Il problema chiave che stai affrontando qui è che hai bisogno di una fonte per il tuo osservabile. In generale è possibile creare osservabili da una varietà di fonti da eventi, delegati, attività, molte delle estensioni osservabili (come .Interval
o .Generate
) e soggetti.
Nel tuo caso devi avere una fonte che puoi avere codice, esterno ai tuoi valori osservabili, push a. In questo caso, un soggetto è perfettamente a posto, ma potresti anche usare un delegato.
Se si utilizza un oggetto, il codice va bene. L'unico lato negativo è che è possibile chiamare updateSubject.OnCompleted
e terminare l'osservabile.
Se si desidera utilizzare un delegato, allora il codice potrebbe essere la seguente:
private Action<GameTime> updateGameTime = null;
public void Initialize()
{
component = new Component();
Observable
.FromEvent<GameTime>(a => updateGameTime += a, a => updateGameTime -= a)
.Subscribe((gameTime) => component.Update(gameTime));
}
public void Update(GameTime gameTime)
{
updateGameTime(gameTime);
}
In questo modo l'unica cosa che si può fare con updateGameTime
si passa in una nuova GameTime
- non si può "accidentalmente "Termina la sequenza.
Ora l'intero problema con l'utilizzo di soggetti rispetto a Observable.Create
è uno stato. Nel tuo codice hai bisogno di stato, quindi un soggetto è OK. In generale però, e quando possibile, è consigliabile incapsulare lo stato - e questo è ciò che Observable.Create
fa per te.
Prendete questo esempio:
var i = -1;
var query =
Observable
.Range(0, 10).Select(x =>
{
i = -i * 2;
return x * i;
});
Se mi iscrivo a questo osservabile due volte mi vengono queste due sequenze:
(1)
0
-4
16
-48
128
-320
768
-1792
4096
-9216
(2)
0
-4096
16384
-49152
131072
-327680
786432
-1835008
4194304
-9437184
La sequenza cambia perché ho usato lo stato (ad es. var i = -1;
).
Se avessi scritto il codice con Observable.Create
ho potuto evitare questo stato:
var query =
Observable
.Create<int>(o =>
{
var i = -1;
return
Observable
.Range(0, 10).Select(x =>
{
i = -i * 2;
return x * i;
})
.Subscribe(o);
});
E 'ancora la stessa query, ma lo Stato è incapsulato, quindi se mi iscrivo due volte ottengo:
(1)
0
-4
16
-48
128
-320
768
-1792
4096
-9216
(2)
0
-4
16
-48
128
-320
768
-1792
4096
-9216
Ci sono momenti in cui la scrittura di query complesse che si potrebbe pensare che l'utilizzo di un soggetto avrebbe reso molto più facile, e, in generale, è lì che si verificano errori. Dovresti sempre cercare di trovare un approccio puramente operatore prima di usare i soggetti in questo caso. Se non è possibile, incapsulare l'uso di un soggetto in Observable.Create
.
volte è tutto come la vostra che l'utilizzo di un soggetto va bene perché è necessario che lo stato esterno.
ho dato un esempio minimo per SO. Il codice reale è più complesso di questo. – sdgfsdh
È bello ascoltarlo. Ma se questo è un esempio completo e verificabile minimamente, allora il Soggetto (e quindi Rx) è ridondante. Non credo che tu fornisca informazioni sufficienti per fornire una risposta sensata. –
Un esempio di dove è utile il mio 'IObservable' è l'elaborazione dell'ingresso. Se ho anche un 'IObservable ' allora posso window usando il mio flusso 'GameTime'. –
sdgfsdh