private void UpdateFinished(Task <QueryEnumerator> runTask) { _isUpdatingAtSequence = 0; if (UpdateQueryTokenSource.IsCancellationRequested) { return; } UpdateQueryTask = null; if (_updateAgain) { Update(); } if (runTask.Status != TaskStatus.RanToCompletion) { Log.To.Query.W(TAG, String.Format("Query Updated task did not run to completion ({0})", runTask.Status), runTask.Exception); return; // NOTE: Assuming that we don't want to lose rows we already retrieved. } _rows = runTask.Result; // NOTE: Should this be 'append' instead of 'replace' semantics? If append, use a concurrent collection. Log.To.Query.I(TAG, "{0} async operation finished", this); LastError = runTask.Exception; var evt = _changed; if (evt == null) { return; // No delegates were subscribed, so no work to be done. } var args = new QueryChangeEventArgs(this, _rows, LastError); evt(this, args); }
/// <summary> /// Called when the underlying query changes. /// </summary> /// <param name="sender">The sender.</param> /// <param name="args">The arguments.</param> private void OnChanged(object sender, QueryChangeEventArgs args) { // $todo(jeff.lill): // // For now, I'm simply going to update the entire collection. In the future, // it may be possible to compare the current collection with the new query // results to try to minimize the changes. This could result in a better // user experience. rowList.Clear(); foreach (var row in liveQuery.Rows) { var entityRow = new EntityQueryRow <TEntity>(row); if (postFilter != null && !postFilter(entityRow)) { continue; } rowList.Add(entityRow); } CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); }
/// <summary> /// Implements the updating of the <see cref="Rows"/> collection. /// </summary> private void Update() { Log.D(Database.Tag, this + ": update() called."); if (View == null) { throw new CouchbaseLiteException("Cannot start LiveQuery when view is null"); } if (!runningState) { Log.D(Database.Tag, this + ": update() called, but running state == false. Ignoring."); return; } if (UpdateQueryTask != null && UpdateQueryTask.Status != TaskStatus.Canceled && UpdateQueryTask.Status != TaskStatus.RanToCompletion) { Log.D(Database.Tag, this + ": already a query in flight, scheduling call to update() once it's done"); if (ReRunUpdateQueryTask != null && ReRunUpdateQueryTask.Status != TaskStatus.Canceled && ReRunUpdateQueryTask.Status != TaskStatus.RanToCompletion) { ReRunUpdateQueryTokenSource.Cancel(); Log.D(Database.Tag, this + ": cancelled rerun update query token source."); } ReRunUpdateQueryTokenSource = new CancellationTokenSource(); Database.Manager.RunAsync(() => { RunUpdateAfterQueryFinishes(); }, ReRunUpdateQueryTokenSource.Token); Log.D(Database.Tag, this + ": RunUpdateAfterQueryFinishes() is fired."); return; } UpdateQueryTokenSource = new CancellationTokenSource(); UpdateQueryTask = RunAsync(base.Run, UpdateQueryTokenSource.Token) .ContinueWith(runTask => { if (runTask.Status != TaskStatus.RanToCompletion) { Log.W(String.Format("Query Updated task did not run to completion ({0})", runTask.Status), runTask.Exception); return; // NOTE: Assuming that we don't want to lose rows we already retrieved. } rows = runTask.Result; // NOTE: Should this be 'append' instead of 'replace' semantics? If append, use a concurrent collection. LastError = runTask.Exception; var evt = Changed; if (evt == null) { return; // No delegates were subscribed, so no work to be done. } var args = new QueryChangeEventArgs(this, rows, LastError); evt(this, args); }); }
private void UpdateFinished(Task<QueryEnumerator> runTask) { _isUpdatingAtSequence = 0; if (UpdateQueryTokenSource.IsCancellationRequested) return; UpdateQueryTask = null; if (_updateAgain) { Update(); } if (runTask.Status != TaskStatus.RanToCompletion) { Log.W(String.Format("Query Updated task did not run to completion ({0})", runTask.Status), runTask.Exception); return; // NOTE: Assuming that we don't want to lose rows we already retrieved. } _rows = runTask.Result; // NOTE: Should this be 'append' instead of 'replace' semantics? If append, use a concurrent collection. Log.D(TAG, "UpdateQueryTask results obtained."); LastError = runTask.Exception; var evt = _changed; if (evt == null) return; // No delegates were subscribed, so no work to be done. var args = new QueryChangeEventArgs (this, _rows, LastError); evt (this, args); }
/// <summary> /// Implements the updating of the <see cref="Rows"/> collection. /// </summary> private void Update() { lock(updateLock) { Log.D(Tag, "update() called."); if (View == null) { throw new CouchbaseLiteException("Cannot start LiveQuery when view is null"); } if (!runningState) { Log.D(Tag, "update() called, but running state == false. Ignoring."); return; } if (UpdateQueryTask != null && UpdateQueryTask.Status != TaskStatus.Canceled && UpdateQueryTask.Status != TaskStatus.RanToCompletion) { Log.D(Tag, "already a query in flight, scheduling call to update() once it's done"); if (ReRunUpdateQueryTask != null && ReRunUpdateQueryTask.Status != TaskStatus.Canceled && ReRunUpdateQueryTask.Status != TaskStatus.RanToCompletion) { ReRunUpdateQueryTokenSource.Cancel(); Log.D(Tag, "cancelled rerun update query token source."); } var updateQueryTaskToWait = UpdateQueryTask; var updateQueryTaskToWaitTokenSource = UpdateQueryTokenSource; ReRunUpdateQueryTokenSource = new CancellationTokenSource(); Database.Manager.RunAsync(() => { RunUpdateAfterQueryFinishes(updateQueryTaskToWait, updateQueryTaskToWaitTokenSource); }, ReRunUpdateQueryTokenSource.Token); Log.D(Tag, "RunUpdateAfterQueryFinishes() is fired."); return; } UpdateQueryTokenSource = new CancellationTokenSource(); UpdateQueryTask = RunAsync(base.Run, UpdateQueryTokenSource.Token) .ContinueWith(runTask => { if (runTask.Status != TaskStatus.RanToCompletion) { Log.W(String.Format("Query Updated task did not run to completion ({0})", runTask.Status), runTask.Exception); return; // NOTE: Assuming that we don't want to lose rows we already retrieved. } rows = runTask.Result; // NOTE: Should this be 'append' instead of 'replace' semantics? If append, use a concurrent collection. LastError = runTask.Exception; var evt = Changed; if (evt == null) return; // No delegates were subscribed, so no work to be done. var args = new QueryChangeEventArgs (this, rows, LastError); evt (this, args); }, Database.Manager.CapturedContext.Scheduler); } }
private void QueryChanged(object sender, QueryChangeEventArgs e) { if (Todos.Count == e.Rows.Count) { return; } Console.WriteLine("Query reports {0} rows", e.Rows.Count); UpdateDataContextSync(e.Rows); }
private void QueryChanged(object sender, QueryChangeEventArgs e) { Console.WriteLine("Found {0} new rows", e.Rows.Count()); UpdateDataContextSync(e.Rows); }