public IProgressObserver Create(ProgressStartEvent begin, Func <Exception, ProgressEndEvent>?onError = null, Func <ProgressEndEvent>?onComplete = null) { if (EqualityComparer <ProgressToken> .Default.Equals(begin.ProgressId, default)) { begin.ProgressId = new ProgressToken(Guid.NewGuid().ToString()); } if (_activeObservers.TryGetValue(begin.ProgressId, out var item)) { return(item); } onError ??= error => new ProgressEndEvent { Message = error.ToString() }; onComplete ??= () => new ProgressEndEvent(); var cts = new CancellationTokenSource(); var observer = new ProgressObserver( _router, begin, onError, onComplete, cts.Token ); _activeObservers.TryAdd(observer.ProgressId, observer); _activeObserverTokens.TryAdd(observer.ProgressId, cts); return(observer); }
public IProgressObserver Create(ProgressStartEvent begin, Func <Exception, ProgressEndEvent>?onError = null, Func <ProgressEndEvent>?onComplete = null) { // ReSharper disable once ConditionIsAlwaysTrueOrFalse if (begin.ProgressId is null) { begin = begin with { ProgressId = new ProgressToken(Guid.NewGuid().ToString()) }; } if (_activeObservers.TryGetValue(begin.ProgressId, out var item)) { return(item); } onError ??= error => new ProgressEndEvent { Message = error.ToString() }; onComplete ??= () => new ProgressEndEvent(); var cts = new CancellationTokenSource(); var observer = new ProgressObserver( _router, begin, onError, onComplete, cts.Token ); _activeObservers.TryAdd(observer.ProgressId, observer); _activeObserverTokens.TryAdd(observer.ProgressId, cts); return(observer); }
public async Task Should_Support_Progress_From_Sever_To_Client() { var(client, server) = await Initialize(ConfigureClient, ConfigureServer); var data = new List <ProgressEvent>(); client.ProgressManager.Progress.Take(1).Switch().Subscribe(x => data.Add(x)); using var workDoneObserver = server.ProgressManager.Create( new ProgressStartEvent { Cancellable = true, Message = "Begin", Percentage = 0, Title = "Work is pending" }, onComplete: () => new ProgressEndEvent { Message = "End" } ); workDoneObserver.OnNext( new ProgressUpdateEvent { Percentage = 10, Message = "Report 1" } ); workDoneObserver.OnNext( new ProgressUpdateEvent { Percentage = 20, Message = "Report 2" } ); workDoneObserver.OnNext( new ProgressUpdateEvent { Percentage = 30, Message = "Report 3" } ); workDoneObserver.OnNext( new ProgressUpdateEvent { Percentage = 40, Message = "Report 4" } ); workDoneObserver.OnCompleted(); await data.DelayUntilCount(6, CancellationToken); var results = data.Select( z => z switch { ProgressStartEvent begin => begin.Message, ProgressUpdateEvent begin => begin.Message, ProgressEndEvent begin => begin.Message, _ => throw new NotSupportedException() }
Task <Unit> IRequestHandler <ProgressStartEvent, Unit> .Handle(ProgressStartEvent request, CancellationToken cancellationToken) { var observable = new ProgressObservable(request.ProgressId); _activeObservables.TryAdd(request.ProgressId, observable); observable.OnNext(request); _observer.OnNext(observable); return(Unit.Task); }
public ProgressObserver( IResponseRouter router, ProgressStartEvent begin, Func <Exception, ProgressEndEvent> onError, Func <ProgressEndEvent> onComplete, CancellationToken cancellationToken ) { ProgressId = begin.ProgressId; _router = router; _onError = onError; _onComplete = onComplete; _disposable = new CompositeDisposable { Disposable.Create(OnCompleted) }; cancellationToken.Register(Dispose); _router.SendNotification(begin); }