/// <summary> /// Creates a <see cref="IObserver{WorkDoneProgressReport}" /> that will send all of its progress information to the same source. /// The other side can cancel this, so the <see cref="CancellationToken" /> should be respected. /// </summary> public ProgressObserver <WorkDoneProgressReport> Create(WorkDoneProgressBegin begin, Func <Exception, WorkDoneProgressEnd> onError = null, Func <WorkDoneProgressEnd> onComplete = null, CancellationToken?cancellationToken = null) { if (!_supported) { return(ProgressObserver <WorkDoneProgressReport> .Noop); } onError ??= error => new WorkDoneProgressEnd() { Message = error.ToString() }; onComplete ??= () => new WorkDoneProgressEnd(); var observer = ProgressObserver.CreateWorkDoneProgress(_router, _serializer, begin, onError, onComplete, cancellationToken ?? CancellationToken.None); _activeObservers.TryAdd(observer.ProgressToken, observer); observer.CancellationToken.Register(() => { if (_activeObservers.TryRemove(observer.ProgressToken, out _)) { observer.OnCompleted(); } }); return(observer); }
/// <summary> /// Creates a <see cref="IObserver{WorkDoneProgressReport}" /> that will send all of its progress information to the same source. /// The other side can cancel this, so the <see cref="CancellationToken" /> should be respected. /// </summary> public ProgressObserver <T> For <T>(ProgressToken token, CancellationToken?cancellationToken = null) { if (!_supported || token == null) { return(ProgressObserver <T> .Noop); } if (_activeObservers.TryGetValue(token, out var item)) { return((ProgressObserver <T>)item); } var observer = ProgressObserver.Create <T>(token, _router, _serializer, cancellationToken ?? CancellationToken.None); _activeObservers.TryAdd(token, observer); observer.CancellationToken.Register(() => { if (_activeObservers.TryRemove(token, out var _)) { observer.OnCompleted(); } }); return(observer); }