Como parte de nuestra aplicación (en la producción de alrededor de 4 meses) tenemos un flujo de datos procedentes de un dispositivo externo que convertimos a un IObservablemétodo preferido para generar un IObservable <String> de una corriente de
Hasta ahora hemos estado utilizando lo siguiente para generarlo, y ha estado funcionando bastante bien.
IObservable<string> ObserveStringStream(Stream inputStream)
{
var streamReader = new StreamReader(inputStream);
return Observable
.Create<string>(observer => Scheduler.ThreadPool
.Schedule(() => ReadLoop(streamReader, observer)));
}
private void ReadLoop(StreamReader reader, IObserver<string> observer)
{
while (true)
{
try
{
var line = reader.ReadLine();
if (line != null)
{
observer.OnNext(line);
}
else
{
observer.OnCompleted();
break;
}
}
catch (Exception ex)
{
observer.OnError(ex);
break;
}
}
}
Anoche me preguntó si había una manera de utilizar la sintaxis yield return
para lograr el mismo resultado y se le ocurrió esto:
IObservable<string> ObserveStringStream(Stream inputStream)
{
var streamReader = new StreamReader(inputStream);
return ReadLoop(streamReader)
.ToObservable(Scheduler.ThreadPool);
}
private IEnumerable<string> ReadLoop(StreamReader reader)
{
while (true)
{
var line = reader.ReadLine();
if (line != null)
{
yield return line;
}
else
{
yield break;
}
}
}
Parece que funciona bastante bien y es mucho más limpio, pero me preguntaba si había pros o contras de una manera sobre la otra, o si había una mejor manera completamente.
Pro: 'return' rendimiento apoya perezoso carga/tardía de su colección. –
Con: cuando se lanza una excepción, no llama a OnException, simplemente se dispara –
Supongo que depende si no te importa grabar un hilo para hacer tu ciclo de lectura, que se reduce a la cantidad de dispositivos que necesitas admitir. Escribí un AsyncTextReader que era él mismo Observable para hacer algo similar, pero a escala. Seguramente en estos días usted podría ESPERAR algo ... –
piers7