/// <summary> /// Receive consumer using task completion source as notification. /// </summary> /// <param name="ct"></param> /// <returns></returns> public Task ReceiveAsync(CancellationToken ct) { if (_open.IsCancellationRequested || _consumerQueue.IsAddingCompleted) { throw new ProxyException(SocketError.Closed); } Message message; if (ReceiveQueue.TryPeek(out message)) { return(Task.FromResult(true)); } else { // Add cancellable item to signal on completion var tcs = new TaskCompletionSource <bool>(); ct.Register(() => { tcs.TrySetCanceled(); }); try { _consumerQueue.Add(tcs, _open.Token); } catch (OperationCanceledException) { } catch (Exception ex) { // Continue waiting for receives as long as we are not cancelled ProxyEventSource.Log.HandledExceptionAsInformation(this, ex); } ct.ThrowIfCancellationRequested(); return(tcs.Task); } }