Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apiCount.include.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
**API count: 661**
**API count: 669**
16 changes: 16 additions & 0 deletions api_list.include.md
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,14 @@
* `IAsyncEnumerable<Task<TResult>> WhenEach<TResult>(IEnumerable<Task<TResult>>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.wheneach?view=net-10.0)


#### TcpClient

* `ValueTask ConnectAsync(IPAddress, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipaddress-system-int32-system-threading-cancellationtoken))
* `ValueTask ConnectAsync(IPAddress[], int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipaddress()-system-int32-system-threading-cancellationtoken))
* `ValueTask ConnectAsync(IPEndPoint, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipendpoint-system-threading-cancellationtoken))
* `ValueTask ConnectAsync(string, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-string-system-int32-system-threading-cancellationtoken))


#### TextReader

* `ValueTask<int> ReadAsync(Memory<char>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync?view=net-10.0#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken))
Expand Down Expand Up @@ -828,6 +836,14 @@
* `bool IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter?view=net-10.0)


#### UdpClient

* `ValueTask<UdpReceiveResult> ReceiveAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.receiveasync?view=net-10.0#system-net-sockets-udpclient-receiveasync(system-threading-cancellationtoken))
* `ValueTask<int> SendAsync(ReadOnlyMemory<byte>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.sendasync?view=net-10.0#system-net-sockets-udpclient-sendasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken))
* `ValueTask<int> SendAsync(ReadOnlyMemory<byte>, IPEndPoint?, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.sendasync?view=net-10.0#system-net-sockets-udpclient-sendasync(system-readonlymemory((system-byte))-system-net-ipendpoint-system-threading-cancellationtoken))
* `ValueTask<int> SendAsync(ReadOnlyMemory<byte>, string?, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.sendasync?view=net-10.0#system-net-sockets-udpclient-sendasync(system-readonlymemory((system-byte))-system-string-system-int32-system-threading-cancellationtoken))


#### UInt16

* `bool TryFormat(Span<byte>, int, ReadOnlySpan<char>, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat?view=net-10.0#system-uint16-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider))
Expand Down
22 changes: 19 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The package targets `netstandard2.0` and is designed to support the following ru
* `uap10`


**API count: 661**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->
**API count: 669**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->


**See [Milestones](../../milestones?state=closed) for release notes.**
Expand Down Expand Up @@ -1226,6 +1226,14 @@ The class `Polyfill` includes the following extension methods:
* `IAsyncEnumerable<Task<TResult>> WhenEach<TResult>(IEnumerable<Task<TResult>>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.wheneach?view=net-10.0)


#### TcpClient

* `ValueTask ConnectAsync(IPAddress, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipaddress-system-int32-system-threading-cancellationtoken))
* `ValueTask ConnectAsync(IPAddress[], int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipaddress()-system-int32-system-threading-cancellationtoken))
* `ValueTask ConnectAsync(IPEndPoint, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipendpoint-system-threading-cancellationtoken))
* `ValueTask ConnectAsync(string, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-string-system-int32-system-threading-cancellationtoken))


#### TextReader

* `ValueTask<int> ReadAsync(Memory<char>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync?view=net-10.0#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken))
Expand Down Expand Up @@ -1273,6 +1281,14 @@ The class `Polyfill` includes the following extension methods:
* `bool IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter?view=net-10.0)


#### UdpClient

* `ValueTask<UdpReceiveResult> ReceiveAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.receiveasync?view=net-10.0#system-net-sockets-udpclient-receiveasync(system-threading-cancellationtoken))
* `ValueTask<int> SendAsync(ReadOnlyMemory<byte>, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.sendasync?view=net-10.0#system-net-sockets-udpclient-sendasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken))
* `ValueTask<int> SendAsync(ReadOnlyMemory<byte>, IPEndPoint?, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.sendasync?view=net-10.0#system-net-sockets-udpclient-sendasync(system-readonlymemory((system-byte))-system-net-ipendpoint-system-threading-cancellationtoken))
* `ValueTask<int> SendAsync(ReadOnlyMemory<byte>, string?, int, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.udpclient.sendasync?view=net-10.0#system-net-sockets-udpclient-sendasync(system-readonlymemory((system-byte))-system-string-system-int32-system-threading-cancellationtoken))


#### UInt16

* `bool TryFormat(Span<byte>, int, ReadOnlySpan<char>, IFormatProvider?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat?view=net-10.0#system-uint16-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider))
Expand Down Expand Up @@ -1603,7 +1619,7 @@ void ArgumentExceptionExample(Order order, Customer customer, string customerId,
this.quantity = quantity;
}
```
<sup><a href='/src/Consume/Consume.cs#L384-L402' title='Snippet source file'>snippet source</a> | <a href='#snippet-ArgumentExceptionUsage' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/Consume/Consume.cs#L386-L404' title='Snippet source file'>snippet source</a> | <a href='#snippet-ArgumentExceptionUsage' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


Expand All @@ -1622,7 +1638,7 @@ void EnsureExample(Order order, Customer customer, string customerId, string ema
this.quantity = Ensure.NotNegativeOrZero(quantity);
}
```
<sup><a href='/src/Consume/Consume.cs#L408-L420' title='Snippet source file'>snippet source</a> | <a href='#snippet-EnsureUsage' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/Consume/Consume.cs#L410-L422' title='Snippet source file'>snippet source</a> | <a href='#snippet-EnsureUsage' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


Expand Down
26 changes: 26 additions & 0 deletions src/Consume/Consume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -492,6 +494,30 @@ void HttpContent_Methods(ByteArrayContent target)
}
#endif

#if FeatureValueTask
async Task TcpClient_Methods()
{
using var client = new TcpClient();
await client.ConnectAsync(IPAddress.Loopback, 12345, CancellationToken.None);
await client.ConnectAsync(new[] { IPAddress.Loopback }, 12345, CancellationToken.None);
await client.ConnectAsync("localhost", 12345, CancellationToken.None);
await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 12345), CancellationToken.None);
}

async Task UdpClient_Methods()
{
using var client = new UdpClient(0);
await client.ReceiveAsync(CancellationToken.None);
#if FeatureMemory
var data = new ReadOnlyMemory<byte>(new byte[] { 1, 2, 3 });
using var connectedClient = new UdpClient("localhost", 12345);
await connectedClient.SendAsync(data, CancellationToken.None);
await client.SendAsync(data, new IPEndPoint(IPAddress.Loopback, 12345), CancellationToken.None);
await client.SendAsync(data, "localhost", 12345, CancellationToken.None);
#endif
}
#endif

void IDictionary_Methods()
{
IDictionary<int, int> idictionary = new Dictionary<int, int>();
Expand Down
175 changes: 175 additions & 0 deletions src/Polyfill/Polyfill_TcpClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#if FeatureValueTask

namespace Polyfills;

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;

static partial class Polyfill
{
#if !NET5_0_OR_GREATER

/// <summary>
/// Connects the client to a remote TCP host using the specified IP address and port number as an asynchronous operation.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipaddress-system-int32-system-threading-cancellationtoken)
public static ValueTask ConnectAsync(
this TcpClient target,
IPAddress address,
int port,
CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return new ValueTask(Task.FromCanceled(cancellationToken));
}

return new ValueTask(ConnectWithCancellationAsync(target, address, port, cancellationToken));
}

/// <summary>
/// Connects the client to a remote TCP host using the specified IP addresses and port number as an asynchronous operation.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipaddress()-system-int32-system-threading-cancellationtoken)
public static ValueTask ConnectAsync(
this TcpClient target,
IPAddress[] addresses,
int port,
CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return new ValueTask(Task.FromCanceled(cancellationToken));
}

return new ValueTask(ConnectWithCancellationAsync(target, addresses, port, cancellationToken));
}

/// <summary>
/// Connects the client to a remote TCP host using the specified host and port number as an asynchronous operation.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-string-system-int32-system-threading-cancellationtoken)
public static ValueTask ConnectAsync(
this TcpClient target,
string host,
int port,
CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return new ValueTask(Task.FromCanceled(cancellationToken));
}

return new ValueTask(ConnectWithCancellationAsync(target, host, port, cancellationToken));
}

static async Task ConnectWithCancellationAsync(
TcpClient target,
IPAddress address,
int port,
CancellationToken cancellationToken)
{
using var registration = cancellationToken.Register(() => target.Close());
try
{
await target.ConnectAsync(address, port);
}
catch (ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
catch (SocketException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
}

static async Task ConnectWithCancellationAsync(
TcpClient target,
IPAddress[] addresses,
int port,
CancellationToken cancellationToken)
{
using var registration = cancellationToken.Register(() => target.Close());
try
{
await target.ConnectAsync(addresses, port);
}
catch (ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
catch (SocketException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
}

static async Task ConnectWithCancellationAsync(
TcpClient target,
string host,
int port,
CancellationToken cancellationToken)
{
using var registration = cancellationToken.Register(() => target.Close());
try
{
await target.ConnectAsync(host, port);
}
catch (ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
catch (SocketException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
}

#endif

#if !NET6_0_OR_GREATER

/// <summary>
/// Connects the client to a remote TCP host using the specified endpoint as an asynchronous operation.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.connectasync?view=net-10.0#system-net-sockets-tcpclient-connectasync(system-net-ipendpoint-system-threading-cancellationtoken)
public static ValueTask ConnectAsync(
this TcpClient target,
IPEndPoint remoteEP,
CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
return new ValueTask(Task.FromCanceled(cancellationToken));
}

return new ValueTask(ConnectWithCancellationIPEndPointAsync(target, remoteEP, cancellationToken));
}

static async Task ConnectWithCancellationIPEndPointAsync(
TcpClient target,
IPEndPoint remoteEP,
CancellationToken cancellationToken)
{
using var registration = cancellationToken.Register(() => target.Close());
try
{
await target.ConnectAsync(remoteEP.Address, remoteEP.Port);
}
catch (ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
catch (SocketException) when (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
}

#endif
}
#endif
Loading