private async Task RunProgressLoopAsync(CancellationToken cancelToken) { //Pici.Log.debug(typeof(SearchSession), "enter progress loop"); try { while (!cancelToken.IsCancellationRequested && Status.progress < 1) { SearchStatus newStatus = await PP2_Stat(cancelToken); if (Status.progress < newStatus.progress || Status.hits < newStatus.hits || Status.records < newStatus.records) { Status = newStatus; } //delay with cancellation await Task.Delay(Pazpar2Settings.DELAY_STAT_REQUEST, cancelToken); } } catch (OperationCanceledException) { throw; } catch (Exception ex) { Pici.Log.error(typeof(SearchSession), "ping loop error ", ex); throw; } //Pici.Log.debug(typeof(SearchSession), "exit progress loop \r\n"); }
private async Task <SearchStatus> PP2_Stat(CancellationToken cancelToken) { try { cancelToken.ThrowIfCancellationRequested(); using (Stream stream = await UrlHelper.GetStatUrl(ID.ToString()).GetStreamAsync()) { SearchStatus newStatus = await Async.DeserializeXml <SearchStatus>(serializerPazPar2Stat, stream, Pazpar2Settings.LOG_HTTP_RESPONSES); //cancel if requested cancelToken.ThrowIfCancellationRequested(); return(newStatus); } } catch (OperationCanceledException) { throw; } catch (Exception ex) { if (ex.IsCanceledException()) { //do nothing here } else { Pici.Log.error(typeof(SearchSession), "stat request error", ex); } throw; } }
private async Task RunQuery(SearchRequest sr) { bool successful = false; try { //cancel running request RunQueryCancelTokenSource.Cancel(); RunQueryCancelTokenSource = new CancellationTokenSource(); CancellationTokenSource CancelTokenSource = RunQueryCancelTokenSource.JoinToLinked(Callback.CancellationToken.Value); //wait & lock await RunQuerySemaphore.WaitAsync(CancelTokenSource.Token); //reset progress IsRunningQuery = true; Status = new SearchStatus(); if (QueryStarted != null) { QueryStarted(sr); } //running query Pici.Log.debug(typeof(SearchSession), "running query"); await PP2_Query(sr); CancelTokenSource.ThrowIfCancellationRequested(); // run 'termlist' loop Task termlistLoopTask = RunTermslistLoopAsync(CancelTokenSource.Token); // run 'stat' loop (show, record) Task progressLoopTask = RunProgressLoopAsync(CancelTokenSource.Token); //wait all Task[] tasks = new Task[] { termlistLoopTask, progressLoopTask }; await Task.WhenAll(tasks); CancelTokenSource.ThrowIfCancellationRequested(); //prolong status progress updates to get changes after 100% //Task prolongStatusProgress = ProlongStatusProgressAfterFinish(CancelTokenSource.Token); successful = true; } catch (OperationCanceledException) { Pici.Log.debug(typeof(SearchSession), "query cancelled."); throw; } catch (Exception ex) { Pici.Log.error(typeof(SearchSession), "error running query", ex); throw; } finally { //update final status //if (!successful) // Status.progress = 2; IsRunningQuery = false; //unlock RunQuerySemaphore.Release(); } }
protected virtual void OnStatusChanged(SearchStatus oldStatus, SearchStatus newStatus) { RaisePropertyChanged("Status", oldStatus, newStatus); if (StatusChanged != null) { StatusChanged(this, new PropertyChangedEventArgs <SearchStatus>("Status", oldStatus, newStatus)); } Callback.ReportStatus(newStatus); }
public void Start(List <Hit> hits, SearchRequest sr, SearchCallback <SearchStatus> statusCallback) { WaitUntilQueryFinishes(statusCallback.CancellationToken.Value); this.Callback = statusCallback; this.Request = sr; FakeHits = hits; Status = new SearchStatus(); if (QueryStarted != null) { QueryStarted(null); } Status = new SearchStatus() { progress = 1.0, hits = hits.Count }; }
private async Task ProlongStatusProgressAfterFinish(CancellationToken cancelToken) { int updateDelay = 1000; Func <Task, Task> statusUpdateTask = async(t) => { SearchStatus newStatus = await PP2_Stat(cancelToken); //let progress grow by 0.01 after 100% was reached once if (Status.progress >= 1.0d && newStatus.progress == 1.0d) { newStatus.progress = Status.progress + 0.01; Status = newStatus; } }; await Task.Delay(updateDelay, cancelToken) .ContinueWith(statusUpdateTask) .ContinueWith(async(t) => await Task.Delay(updateDelay, cancelToken)) .ContinueWith(statusUpdateTask) .ContinueWith(async(t) => await Task.Delay(updateDelay, cancelToken)) .ContinueWith(statusUpdateTask) .ContinueWith(async(t) => await Task.Delay(updateDelay, cancelToken)) .ContinueWith(statusUpdateTask); }