未验证 提交 b90a734e 编写于 作者: R Radek Zikmund 提交者: GitHub

Add missing documentation to System.Net.Quic and System.Net.WebSockets (#74945)

* Fix the inheritdoc cref on Quic* classes

* Add missing documentation

* WIP

* Add summary and exception annotation to Stream overriden members

* Code review feedback
上级 49400597
......@@ -160,6 +160,8 @@ private T GetSpecializedCollection<T>(int slot, Func<HttpRequestHeaders, T> crea
set { SetOrRemoveParsedValue(KnownHeaders.MaxForwards.Descriptor, value); }
}
/// <summary>Gets or sets the value of the <see langword=":protocol" /> pseudo-header for an HTTP request.</summary>
/// <value>The value of the <see langword=":protocol" /> pseudo-header for an HTTP request.</value>
public string? Protocol
{
get => _protocol;
......
......@@ -64,6 +64,8 @@ public static HttpMethod Patch
get { return s_patchMethod; }
}
/// <summary>Gets the HTTP CONNECT protocol method.</summary>
/// <value>The HTTP CONNECT method.</value>
public static HttpMethod Connect
{
get { return s_connectMethod; }
......
......@@ -167,7 +167,7 @@ public static async ValueTask<QuicConnection> ConnectAsync(QuicClientConnectionO
/// </summary>
public SslApplicationProtocol NegotiatedApplicationProtocol => _negotiatedApplicationProtocol;
/// <inheritdoc cref="ToString"/>
/// <inheritdoc />
public override string ToString() => _handle.ToString();
/// <summary>
......
......@@ -93,7 +93,7 @@ public static ValueTask<QuicListener> ListenAsync(QuicListenerOptions options, C
/// </summary>
public IPEndPoint LocalEndPoint { get; }
/// <inheritdoc cref="ToString"/>
/// <inheritdoc />
public override string ToString() => _handle.ToString();
/// <summary>
......@@ -157,6 +157,7 @@ private unsafe QuicListener(QuicListenerOptions options)
/// Propagates exceptions from <see cref="QuicListenerOptions.ConnectionOptionsCallback"/>, including validation errors from misconfigured <see cref="QuicServerConnectionOptions"/>, e.g. <see cref="ArgumentException"/>.
/// Also propagates exceptions from failed connection handshake, e.g. <see cref="AuthenticationException"/>, <see cref="QuicException"/>.
/// </remarks>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the asynchronous operation.</param>
/// <returns>A task that will contain a fully connected <see cref="QuicConnection" /> which successfully finished the handshake and is ready to be used.</returns>
public async ValueTask<QuicConnection> AcceptConnectionAsync(CancellationToken cancellationToken = default)
{
......
......@@ -13,16 +13,39 @@ namespace System.Net.Quic;
public partial class QuicStream : Stream
{
// Seek and length.
/// <inheritdoc />
/// <summary>Gets a value indicating whether the <see cref="QuicStream" /> supports seeking.</summary>
public override bool CanSeek => false;
/// <inheritdoc />
/// <summary>Gets the length of the data available on the stream. This property is not currently supported and always throws a <see cref="NotSupportedException" />.</summary>
/// <exception cref="NotSupportedException">In all cases.</exception>
public override long Length => throw new NotSupportedException();
/// <inheritdoc />
/// <summary>Gets or sets the position within the current stream. This property is not currently supported and always throws a <see cref="NotSupportedException" />.</summary>
/// <exception cref="NotSupportedException">In all cases.</exception>
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
/// <inheritdoc />
/// <summary>Sets the current position of the stream to the given value. This method is not currently supported and always throws a <see cref="NotSupportedException" />.</summary>
/// <exception cref="NotSupportedException">In all cases.</exception>
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
/// <inheritdoc />
/// <summary>Sets the length of the stream. This method is not currently supported and always throws a <see cref="NotSupportedException" />.</summary>
/// <exception cref="NotSupportedException">In all cases.</exception>
public override void SetLength(long value) => throw new NotSupportedException();
// Read and Write timeouts.
/// <inheritdoc />
/// <summary>Gets a value that indicates whether the <see cref="QuicStream" /> can timeout.</summary>
public override bool CanTimeout => true;
private TimeSpan _readTimeout = Timeout.InfiniteTimeSpan;
private TimeSpan _writeTimeout = Timeout.InfiniteTimeSpan;
/// <inheritdoc />
public override int ReadTimeout
{
get
......@@ -40,6 +63,8 @@ public override int ReadTimeout
_readTimeout = TimeSpan.FromMilliseconds(value);
}
}
/// <inheritdoc />
public override int WriteTimeout
{
get
......@@ -59,21 +84,33 @@ public override int WriteTimeout
}
// Read boilerplate.
/// <inheritdoc />
/// <summary>Gets a value indicating whether the <see cref="QuicStream" /> supports reading.</summary>
public override bool CanRead => Volatile.Read(ref _disposed) == 0 && _canRead;
/// <inheritdoc />
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
=> TaskToApm.Begin(ReadAsync(buffer, offset, count, default), callback, state);
/// <inheritdoc />
public override int EndRead(IAsyncResult asyncResult)
=> TaskToApm.End<int>(asyncResult);
/// <inheritdoc />
public override int Read(byte[] buffer, int offset, int count)
{
ValidateBufferArguments(buffer, offset, count);
return Read(buffer.AsSpan(offset, count));
}
/// <inheritdoc />
public override int ReadByte()
{
byte b = 0;
return Read(MemoryMarshal.CreateSpan(ref b, 1)) != 0 ? b : -1;
}
/// <inheritdoc />
public override int Read(Span<byte> buffer)
{
ObjectDisposedException.ThrowIf(_disposed == 1, this);
......@@ -101,6 +138,8 @@ public override int Read(Span<byte> buffer)
cts?.Dispose();
}
}
/// <inheritdoc />
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default)
{
ValidateBufferArguments(buffer, offset, count);
......@@ -108,20 +147,32 @@ public override Task<int> ReadAsync(byte[] buffer, int offset, int count, Cancel
}
// Write boilerplate.
/// <inheritdoc />
/// <summary>Gets a value indicating whether the <see cref="QuicStream" /> supports writing.</summary>
public override bool CanWrite => Volatile.Read(ref _disposed) == 0 && _canWrite;
/// <inheritdoc />
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
=> TaskToApm.Begin(WriteAsync(buffer, offset, count, default), callback, state);
/// <inheritdoc />
public override void EndWrite(IAsyncResult asyncResult)
=> TaskToApm.End(asyncResult);
/// <inheritdoc />
public override void Write(byte[] buffer, int offset, int count)
{
ValidateBufferArguments(buffer, offset, count);
Write(buffer.AsSpan(offset, count));
}
/// <inheritdoc />
public override void WriteByte(byte value)
{
Write(MemoryMarshal.CreateReadOnlySpan(ref value, 1));
}
/// <inheritdoc />
public override void Write(ReadOnlySpan<byte> buffer)
{
ObjectDisposedException.ThrowIf(_disposed == 1, this);
......@@ -145,6 +196,8 @@ public override void Write(ReadOnlySpan<byte> buffer)
cts?.Dispose();
}
}
/// <inheritdoc />
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default)
{
ValidateBufferArguments(buffer, offset, count);
......@@ -152,13 +205,18 @@ public override Task WriteAsync(byte[] buffer, int offset, int count, Cancellati
}
// Flush.
/// <inheritdoc />
public override void Flush()
=> FlushAsync().GetAwaiter().GetResult();
/// <inheritdoc />
public override Task FlushAsync(CancellationToken cancellationToken = default)
// NOP for now
=> Task.CompletedTask;
// Dispose.
/// <inheritdoc />
protected override void Dispose(bool disposing)
{
DisposeAsync().AsTask().GetAwaiter().GetResult();
......
......@@ -126,7 +126,7 @@ public sealed partial class QuicStream
/// </summary>
public Task WritesClosed => _sendTcs.GetFinalTask();
/// <inheritdoc cref="ToString"/>
/// <inheritdoc />
public override string ToString() => _handle.ToString();
/// <summary>
......@@ -233,7 +233,7 @@ internal ValueTask StartAsync(CancellationToken cancellationToken = default)
return valueTask;
}
/// <inheritdoc cref="ReadAsync(System.Memory{byte},System.Threading.CancellationToken)"/>
/// <inheritdoc />
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
{
ObjectDisposedException.ThrowIf(_disposed == 1, this);
......@@ -307,12 +307,12 @@ public override async ValueTask<int> ReadAsync(Memory<byte> buffer, Cancellation
return totalCopied;
}
/// <inheritdoc cref="WriteAsync(System.ReadOnlyMemory{byte},System.Threading.CancellationToken)"/>
/// <inheritdoc />
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
=> WriteAsync(buffer, completeWrites: false, cancellationToken);
/// <inheritdoc cref="WriteAsync(System.ReadOnlyMemory{byte},System.Threading.CancellationToken)"/>
/// <inheritdoc cref="WriteAsync(ReadOnlyMemory{byte}, CancellationToken)"/>
/// <param name="buffer">The region of memory to write data from.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
/// <param name="completeWrites">Notifies the peer about gracefully closing the write side, i.e.: sends FIN flag with the data.</param>
......@@ -484,8 +484,8 @@ private unsafe int HandleEventStartComplete(ref START_COMPLETE data)
private unsafe int HandleEventReceive(ref RECEIVE data)
{
ulong totalCopied = (ulong)_receiveBuffers.CopyFrom(
new ReadOnlySpan<QUIC_BUFFER>(data.Buffers, (int) data.BufferCount),
(int) data.TotalBufferLength,
new ReadOnlySpan<QUIC_BUFFER>(data.Buffers, (int)data.BufferCount),
(int)data.TotalBufferLength,
data.Flags.HasFlag(QUIC_RECEIVE_FLAGS.FIN));
if (NetEventSource.Log.IsEnabled())
......
......@@ -73,11 +73,24 @@ public override WebSocketState State
}
}
/// <summary>
/// Connects to a WebSocket server as an asynchronous operation.
/// </summary>
/// <param name="uri">The URI of the WebSocket server to connect to.</param>
/// <param name="cancellationToken">A cancellation token used to propagate notification that the operation should be canceled.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
public Task ConnectAsync(Uri uri, CancellationToken cancellationToken)
{
return ConnectAsync(uri, null, cancellationToken);
}
/// <summary>
/// Connects to a WebSocket server as an asynchronous operation.
/// </summary>
/// <param name="uri">The URI of the WebSocket server to connect to.</param>
/// <param name="invoker">The <see cref="HttpMessageInvoker" /> instance to use for connecting.</param>
/// <param name="cancellationToken">A cancellation token used to propagate notification that the operation should be canceled.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
public Task ConnectAsync(Uri uri, HttpMessageInvoker? invoker, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(uri);
......
......@@ -42,6 +42,8 @@ public sealed class ClientWebSocketOptions
#region HTTP Settings
/// <summary>Gets or sets the HTTP version to use.</summary>
/// <value>The HTTP message version. The default value is <c>1.1</c>.</value>
public Version HttpVersion
{
get => _version;
......@@ -54,6 +56,8 @@ public Version HttpVersion
}
}
/// <summary>Gets or sets the policy that determines how <see cref="ClientWebSocketOptions.HttpVersion" /> is interpreted and how the final HTTP version is negotiated with the server.</summary>
/// <value>The version policy used when the HTTP connection is established.</value>
public HttpVersionPolicy HttpVersionPolicy
{
get => _versionPolicy;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册