Là một phần của ứng dụng của chúng tôi (trong sản xuất cho khoảng 4 tháng nay), chúng tôi có một dòng dữ liệu đến từ một thiết bị bên ngoài mà chúng ta chuyển đổi sang một IObservablephương pháp ưa thích để tạo ra một IObservable <String> từ một Stream
Cho đến bây giờ chúng tôi đã sử dụng những điều sau đây để tạo ra nó và nó hoạt động khá tốt.
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;
}
}
}
Đêm qua tôi tự hỏi nếu có một cách để sử dụng cú pháp yield return
để đạt được kết quả tương tự và đến với điều này:
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;
}
}
}
Dường như với hoạt động khá tốt và nó sạch hơn nhiều, nhưng tôi đã tự hỏi liệu có bất kỳ ưu điểm hay khuyết điểm nào trên con đường này hay không, hoặc nếu có một cách tốt hơn hoàn toàn.
Pro: 'năng suất return' hỗ trợ lười biếng/trễ tải của bộ sưu tập của bạn. –
Con: khi một ngoại lệ được ném, nó không gọi OnException, nó chỉ bong bóng lên –
Tôi đoán nó phụ thuộc nếu bạn không nhớ đốt một chuỗi để đọc vòng lặp của bạn, mà đi xuống bao nhiêu thiết bị bạn cần hỗ trợ. Tôi đã viết một AsyncTextReader đó là chính nó quan sát để làm một cái gì đó tương tự, nhưng ở quy mô. Chắc chắn những ngày này bạn có thể AWAIT một cái gì đó ... –
piers7