Buforuj dane z kursora bazy danych, zachowując responsywność interfejsu użytkownika
Mam wypełniony katalog bazy danych i kursor, który może być użyty do pobierania obiektów. Ten katalog może oczywiście być bardzo duży, a to, co chciałbym zrobić, to użyćReactiveUI buforować dane, zachowując powiązanie danych z interfejsem użytkownika i reagowanie. Podążyłem za krokamitutaj przetłumaczyć mojeIEnumerable
wIObservable
, jak pokazano tutaj:
public class CatalogService
{
...
public IObservable<DbObject> DataSource
{
get
{
return Observable.Create<DbObject>(obs =>
{
var cursor = Database.Instance.GetAllObjects();
var status = cursor.MoveToFirst();
while (status == DbStatus.OK)
{
var dbObject= Db.Create(cursor);
obs.OnNext(dbObject);
status = cursor.MoveToNext();
}
obs.OnCompleted();
return Disposable.Empty;
});
}
}
}
W mojej klasie widoku (w szczególnościLoaded
zdarzenie), subskrybuję źródło danych i wykorzystuję metodę bufora w nadziei, że UI będzie w stanie reagować.
public ObservableCollection<DbObject> DbObjects { get; set; }
private async void OnLoad(object sender, RoutedEventArgs e)
{
var observableData = CatalogService.Instance.DataSource.Publish();
var chunked = observableData.Buffer(TimeSpan.FromMilliseconds(100));
var dispatcherObs = chunked.ObserveOnDispatcher(DispatcherPriority.Background);
dispatcherObs.Subscribe(dbObjects =>
{
foreach (var dbObject in dbObjects)
{
DbObjects.Add(dbObject);
}
});
await Task.Run(() => observableData.Connect());
await dispatcherObs.ToTask();
}
Rezultat jest niestety odwrotny. Kiedy kontroluję widok (który zawiera prostyListBox
powiązane z danymi doDbObjects
ładunki), nie pokazuje żadnych danych, dopóki nie zostanie wyliczony cały katalog. Dopiero wtedy odświeżany jest interfejs użytkownika.
Jestem nowy w ReactiveUI, ale jestem pewien, że jest w stanie wykonać to zadanie. Czy ktoś ma jakieś sugestie lub wskazówki, jeśli używam go nieprawidłowo?