public IObservable <Response> Send( [NotNull] Request request, CancellationToken token = default(CancellationToken)) { OverlappingPipeClientStream stream = _stream; if (_state != PipeState.Connected || stream == null) { // ReSharper disable once AssignNullToNotNullAttribute return(Observable.Empty <Response>()); } // ReSharper disable once AssignNullToNotNullAttribute return(Observable.Create <Response>( async(observer, t) => { Debug.Assert(observer != null); using (ITokenSource tokenSource = token.CreateLinked(t)) { token = tokenSource.Token; ConnectedCommand cr = new ConnectedCommand(request, observer); _commandRequests.TryAdd(request.ID, cr); try { await stream.WriteAsync(request.Serialize(), token).ConfigureAwait(false); await cr.CompletionTask.WithCancellation(token).ConfigureAwait(false); } // ReSharper disable once EmptyGeneralCatchClause catch { } // If the command is not explicitly cancelled and is still running, and we've been cancelled // then ask the server to cancel. if (!cr.IsCancelled && !cr.IsCompleted && token.IsCancellationRequested) { try { using (CancellationTokenSource cts = Constants.FireAndForgetTokenSource) await CancelCommand(request.ID, cts.Token).ConfigureAwait(false); } catch (TaskCanceledException) { } } // Remove the command request. _commandRequests.TryRemove(request.ID, out cr); } })); }
/// <summary> /// Removes the specified connected command. /// </summary> /// <param name="connectedCommand">The connected command.</param> public void Remove([NotNull] ConnectedCommand connectedCommand) { ConnectedCommand removed; _commands.TryRemove(connectedCommand.ID, out removed); }
public IObservable<Response> Send( [NotNull] Request request, CancellationToken token = default(CancellationToken)) { OverlappingPipeClientStream stream = _stream; if (_state != PipeState.Connected || stream == null) // ReSharper disable once AssignNullToNotNullAttribute return Observable.Empty<Response>(); // ReSharper disable once AssignNullToNotNullAttribute return Observable.Create<Response>( async (observer, t) => { Debug.Assert(observer != null); using (ITokenSource tokenSource = token.CreateLinked(t)) { token = tokenSource.Token; ConnectedCommand cr = new ConnectedCommand(request, observer); _commandRequests.TryAdd(request.ID, cr); try { await stream.WriteAsync(request.Serialize(), token).ConfigureAwait(false); await cr.CompletionTask.WithCancellation(token).ConfigureAwait(false); } // ReSharper disable once EmptyGeneralCatchClause catch { } // If the command is not explicitly cancelled and is still running, and we've been cancelled // then ask the server to cancel. if (!cr.IsCancelled && !cr.IsCompleted && token.IsCancellationRequested) try { using (CancellationTokenSource cts = Constants.FireAndForgetTokenSource) await CancelCommand(request.ID, cts.Token).ConfigureAwait(false); } catch (TaskCanceledException) { } // Remove the command request. _commandRequests.TryRemove(request.ID, out cr); } }); }