async Task IDuplexMessageStream.OpenAsync(CancellationToken cancellationToken) { ReadCompleted = false; WriteCompleted = false; readStream = await readProvider(cancellationToken).ConfigureAwait(false); writeStream = writeProvider == readProvider ? readStream : await writeProvider(cancellationToken).ConfigureAwait(false); reader = StreamConnection.GetReader(readStream); writer = StreamConnection.GetWriter(writeStream); }
/// <summary> /// Send multiple messages over a stream /// </summary> public static async ValueTask SendAsync <T>(Stream destination, IAsyncEnumerable <T> source, MessagePipeOptions options = default) { var writer = StreamConnection.GetWriter(destination, options.PipeOptions); var tcs = new TaskCompletionSource <object>(); #pragma warning disable CS0618 // this *is* a Pipe; this is fine writer.OnReaderCompleted(s_ReaderCompleted, tcs); // attach to detect when the pipe is drained #pragma warning restore CS0618 await SendAsync <T>(writer, source, options.Without(MessagePipeFlags.LeaveOpen)).ConfigureAwait(false); // send the data await tcs.Task.ConfigureAwait(false); // wait for the pipe to drain await destination.FlushAsync().ConfigureAwait(false); // flush the stream }