commit e85ecc83ab9406fd1089cc587959eb21d83d64da
parent 54f507b485558a201bc314edac955c237ca93332
Author: Mikolaj Lenczewski <mikolaj.lenczewski308@gmail.com>
Date: Sun, 26 Apr 2020 12:35:37 +0100
We have a memory leak on cancellation...but we cancel.
Diffstat:
8 files changed, 264 insertions(+), 209 deletions(-)
diff --git a/NetSharp/NetSharp/NetSharp.xml b/NetSharp/NetSharp/NetSharp.xml
@@ -290,7 +290,7 @@
The remote end point which to which to connect the client.
</param>
</member>
- <member name="M:NetSharp.Sockets.SocketClient.ConnectAsync(System.Net.EndPoint@,System.Threading.CancellationToken)">
+ <member name="M:NetSharp.Sockets.SocketClient.ConnectAsync(System.Net.EndPoint@)">
<summary>
Asynchronously connects the client to the specified end point. If called on a <see cref="F:System.Net.Sockets.SocketType.Dgram" />-based client, this method
configures the default remote host, and the client will ignore any packets not coming from this default host (i.e the given <paramref name="remoteEndPoint" />).
@@ -298,9 +298,6 @@
<param name="remoteEndPoint">
The remote end point which to which to connect the client.
</param>
- <param name="cancellationToken">
- The <see cref="T:System.Threading.CancellationToken" /> upon whose cancellation the connection attempt should be aborted. TODO make functional
- </param>
<returns>
A <see cref="T:System.Threading.Tasks.ValueTask" /> representing the connection attempt.
</returns>
@@ -346,7 +343,7 @@
The completion source which wraps the event-based APM, and provides an awaitable <see cref="T:System.Threading.Tasks.Task" />.
</summary>
</member>
- <member name="M:NetSharp.Sockets.SocketClient.AsyncTransmissionToken.#ctor(System.Threading.Tasks.TaskCompletionSource{NetSharp.Utils.TransmissionResult}@,System.Threading.CancellationToken@)">
+ <member name="M:NetSharp.Sockets.SocketClient.AsyncTransmissionToken.#ctor(System.Threading.Tasks.TaskCompletionSource{NetSharp.Utils.TransmissionResult}@,System.Net.Sockets.SocketAsyncEventArgs@,System.Threading.CancellationToken@)">
<summary>
Constructs a new instance of the <see cref="T:NetSharp.Sockets.SocketClient.AsyncTransmissionToken" /> struct.
</summary>
@@ -567,7 +564,7 @@
<member name="F:NetSharp.Sockets.Stream.StreamSocketClientOptions.PreallocatedTransmissionArgs">
<summary>
The number of <see cref="T:System.Net.Sockets.SocketAsyncEventArgs" /> instances that should be preallocated for use in the
- <see cref="M:NetSharp.Sockets.Stream.StreamSocketClient.SendAsync(System.Memory{System.Byte},System.Net.Sockets.SocketFlags,System.Threading.CancellationToken)" /> and <see cref="M:NetSharp.Sockets.Stream.StreamSocketClient.ReceiveAsync(System.Memory{System.Byte},System.Net.Sockets.SocketFlags,System.Threading.CancellationToken)" /> methods.
+ <see cref="M:NetSharp.Sockets.Stream.StreamSocketClient.SendAsync(System.Memory{System.Byte},System.Net.Sockets.SocketFlags)" /> and <see cref="M:NetSharp.Sockets.Stream.StreamSocketClient.ReceiveAsync(System.Memory{System.Byte},System.Net.Sockets.SocketFlags)" /> methods.
</summary>
</member>
<member name="M:NetSharp.Sockets.Stream.StreamSocketClientOptions.#ctor(System.UInt16)">
diff --git a/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketClient.cs b/NetSharp/NetSharp/Sockets/Datagram/DatagramSocketClient.cs
@@ -61,29 +61,22 @@ namespace NetSharp.Sockets.Datagram
{
AsyncOperationToken connectToken = (AsyncOperationToken)args.UserToken;
- if (connectToken.CancellationToken.IsCancellationRequested)
- {
- connectToken.CompletionSource.SetCanceled();
- }
- else
- {
- switch (args.SocketError)
- {
- case SocketError.Success:
- connectToken.CompletionSource.SetResult(true);
+ if (connectToken.CancellationToken.IsCancellationRequested) return;
- break;
+ switch (args.SocketError)
+ {
+ case SocketError.Success:
+ connectToken.CompletionSource.SetResult(true);
- case SocketError.OperationAborted:
- Debug.WriteLine("CompleteConnect experienced SocketError.OperationAborted!");
+ break;
- break;
+ case SocketError.OperationAborted:
+ break;
- default:
- connectToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+ default:
+ connectToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
- break;
- }
+ break;
}
TransmissionArgsPool.Return(args);
@@ -93,6 +86,12 @@ namespace NetSharp.Sockets.Datagram
{
AsyncTransmissionToken receiveToken = (AsyncTransmissionToken)args.UserToken;
+ if (receiveToken.CancellationToken.IsCancellationRequested)
+ {
+ Debug.WriteLine("ReceiveFrom completed after being cancelled!");
+ return;
+ }
+
switch (args.SocketError)
{
case SocketError.Success:
@@ -103,8 +102,7 @@ namespace NetSharp.Sockets.Datagram
break;
case SocketError.OperationAborted:
- Debug.WriteLine("CompleteReceiveFrom experienced SocketError.OperationAborted!");
-
+ Debug.WriteLine("ReceiveFrom received operation aborted!");
break;
default:
@@ -120,31 +118,24 @@ namespace NetSharp.Sockets.Datagram
{
AsyncTransmissionToken sendToken = (AsyncTransmissionToken)args.UserToken;
- if (sendToken.CancellationToken.IsCancellationRequested)
- {
- sendToken.CompletionSource.SetCanceled();
- }
- else
- {
- switch (args.SocketError)
- {
- case SocketError.Success:
- TransmissionResult result = new TransmissionResult(in args);
+ if (sendToken.CancellationToken.IsCancellationRequested) return;
- sendToken.CompletionSource.SetResult(result);
+ switch (args.SocketError)
+ {
+ case SocketError.Success:
+ TransmissionResult result = new TransmissionResult(in args);
- break;
+ sendToken.CompletionSource.SetResult(result);
- case SocketError.OperationAborted:
- Debug.WriteLine("CompleteSendTo experienced SocketError.OperationAborted!");
+ break;
- break;
+ case SocketError.OperationAborted:
+ break;
- default:
- sendToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+ default:
+ sendToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
- break;
- }
+ break;
}
TransmissionArgsPool.Return(args);
@@ -222,12 +213,23 @@ namespace NetSharp.Sockets.Datagram
args.RemoteEndPoint = remoteEndPoint;
args.SocketFlags = flags;
- args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken);
+ args.UserToken = new AsyncTransmissionToken(in tcs, in args, cancellationToken);
+
+ // TODO find out why the fricc we leak memory
+ CancellationTokenRegistration cancellationRegistration =
+ cancellationToken.Register(CancelAsyncTransmissionCallback, args.UserToken);
- // TODO implement cancellation for client socket receiveFromAsync
- cancellationToken.Register(CancelAsyncTransmissionCallback, new object());
+ if (Connection.ReceiveFromAsync(args))
+ return new ValueTask<TransmissionResult>(
+ tcs.Task.ContinueWith((task, state) =>
+ {
+ ((CancellationTokenRegistration)state).Dispose();
- if (Connection.ReceiveFromAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task);
+ return task.Result;
+ }, cancellationRegistration, CancellationToken.None)
+ );
+
+ cancellationRegistration.Dispose();
TransmissionResult result = new TransmissionResult(in args);
@@ -254,12 +256,23 @@ namespace NetSharp.Sockets.Datagram
args.RemoteEndPoint = remoteEndPoint;
args.SocketFlags = flags;
- args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken);
+ args.UserToken = new AsyncTransmissionToken(in tcs, in args, cancellationToken);
+
+ // TODO find out why the fricc we leak memory
+ CancellationTokenRegistration cancellationRegistration =
+ cancellationToken.Register(CancelAsyncTransmissionCallback, args.UserToken);
+
+ if (Connection.SendToAsync(args))
+ return new ValueTask<TransmissionResult>(
+ tcs.Task.ContinueWith((task, state) =>
+ {
+ ((CancellationTokenRegistration)state).Dispose();
- // TODO implement cancellation for client socket sendToAsync
- cancellationToken.Register(CancelAsyncTransmissionCallback, new object());
+ return task.Result;
+ }, cancellationRegistration, CancellationToken.None)
+ );
- if (Connection.SendToAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task);
+ cancellationRegistration.Dispose();
TransmissionResult result = new TransmissionResult(in args);
diff --git a/NetSharp/NetSharp/Sockets/SocketClient.cs b/NetSharp/NetSharp/Sockets/SocketClient.cs
@@ -39,9 +39,13 @@ namespace NetSharp.Sockets
{
}
- protected void CancelAsyncTransmissionCallback(object tokenObj)
+ protected void CancelAsyncTransmissionCallback(object state)
{
- Debug.WriteLine("Cancelling asynchronous transmission!");
+ AsyncTransmissionToken token = (AsyncTransmissionToken)state;
+
+ token.CompletionSource.SetResult(TransmissionResult.Timeout);
+
+ DestroyTransmissionArgs(token.TransmissionArgs);
}
/// <summary>
@@ -63,9 +67,6 @@ namespace NetSharp.Sockets
/// <param name="remoteEndPoint">
/// The remote end point which to which to connect the client.
/// </param>
- /// <param name="cancellationToken">
- /// The <see cref="CancellationToken" /> upon whose cancellation the connection attempt should be aborted. TODO make functional
- /// </param>
/// <returns>
/// A <see cref="ValueTask" /> representing the connection attempt.
/// </returns>
@@ -76,9 +77,23 @@ namespace NetSharp.Sockets
SocketAsyncEventArgs args = TransmissionArgsPool.Rent();
args.RemoteEndPoint = remoteEndPoint;
- args.UserToken = new AsyncOperationToken(in tcs, in cancellationToken);
+ args.UserToken = new AsyncOperationToken(in tcs, CancellationToken.None);
+
+ // TODO find out why the fricc we leak memory
+ CancellationTokenRegistration cancellationRegistration =
+ cancellationToken.Register(CancelAsyncTransmissionCallback, args.UserToken);
- if (Connection.ConnectAsync(args)) return new ValueTask(tcs.Task);
+ if (Connection.ConnectAsync(args))
+ return new ValueTask(
+ tcs.Task.ContinueWith((task, state) =>
+ {
+ ((CancellationTokenRegistration)state).Dispose();
+
+ return task.Result;
+ }, cancellationRegistration, CancellationToken.None)
+ );
+
+ cancellationRegistration.Dispose();
TransmissionArgsPool.Return(args);
@@ -132,6 +147,8 @@ namespace NetSharp.Sockets
/// </summary>
public readonly TaskCompletionSource<TransmissionResult> CompletionSource;
+ public readonly SocketAsyncEventArgs TransmissionArgs;
+
/// <summary>
/// Constructs a new instance of the <see cref="AsyncTransmissionToken" /> struct.
/// </summary>
@@ -141,10 +158,12 @@ namespace NetSharp.Sockets
/// <param name="cancellationToken">
/// The cancellation token to observe during the operation.
/// </param>
- public AsyncTransmissionToken(in TaskCompletionSource<TransmissionResult> completionSource, in CancellationToken cancellationToken)
+ public AsyncTransmissionToken(in TaskCompletionSource<TransmissionResult> completionSource, in SocketAsyncEventArgs transmissionArgs, in CancellationToken cancellationToken)
{
CompletionSource = completionSource;
+ TransmissionArgs = transmissionArgs;
+
CancellationToken = cancellationToken;
}
}
diff --git a/NetSharp/NetSharp/Sockets/Stream/StreamSocketClient.cs b/NetSharp/NetSharp/Sockets/Stream/StreamSocketClient.cs
@@ -60,24 +60,23 @@ namespace NetSharp.Sockets.Stream
{
AsyncOperationToken connectToken = (AsyncOperationToken)args.UserToken;
- switch (args.SocketError)
+ if (!connectToken.CancellationToken.IsCancellationRequested)
{
- case SocketError.Success:
- connectToken.CompletionSource.SetResult(true);
+ switch (args.SocketError)
+ {
+ case SocketError.Success:
+ connectToken.CompletionSource.SetResult(true);
- break;
-
- case SocketError.OperationAborted:
- Debug.WriteLine("CompleteConnect experienced SocketError.OperationAborted!");
-
- connectToken.CompletionSource.SetResult(false);
+ break;
- break;
+ case SocketError.OperationAborted:
+ break;
- default:
- connectToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+ default:
+ connectToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
- break;
+ break;
+ }
}
TransmissionArgsPool.Return(args);
@@ -87,24 +86,23 @@ namespace NetSharp.Sockets.Stream
{
AsyncOperationToken disconnectToken = (AsyncOperationToken)args.UserToken;
- switch (args.SocketError)
+ if (!disconnectToken.CancellationToken.IsCancellationRequested)
{
- case SocketError.Success:
- disconnectToken.CompletionSource.SetResult(true);
+ switch (args.SocketError)
+ {
+ case SocketError.Success:
+ disconnectToken.CompletionSource.SetResult(true);
- break;
-
- case SocketError.OperationAborted:
- Debug.WriteLine("CompleteDisconnect experienced SocketError.OperationAborted!");
-
- disconnectToken.CompletionSource.SetResult(false);
+ break;
- break;
+ case SocketError.OperationAborted:
+ break;
- default:
- disconnectToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+ default:
+ disconnectToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
- break;
+ break;
+ }
}
TransmissionArgsPool.Return(args);
@@ -114,58 +112,57 @@ namespace NetSharp.Sockets.Stream
{
AsyncTransmissionToken receiveToken = (AsyncTransmissionToken)args.UserToken;
- switch (args.SocketError)
+ if (!receiveToken.CancellationToken.IsCancellationRequested)
{
- case SocketError.Success:
- Memory<byte> transmissionBuffer = args.MemoryBuffer;
- int expectedBytes = transmissionBuffer.Length;
+ switch (args.SocketError)
+ {
+ case SocketError.Success:
+ Memory<byte> transmissionBuffer = args.MemoryBuffer;
+ int expectedBytes = transmissionBuffer.Length;
- if (args.BytesTransferred == expectedBytes)
- {
- // buffer was fully received
-
- TransmissionResult result = new TransmissionResult(in args);
-
- receiveToken.CompletionSource.SetResult(result);
+ if (args.BytesTransferred == expectedBytes)
+ {
+ // buffer was fully received
- TransmissionArgsPool.Return(args);
- }
- else if (expectedBytes > args.BytesTransferred && args.BytesTransferred > 0)
- {
- // receive the remaining parts of the buffer
+ TransmissionResult result = new TransmissionResult(in args);
- int receivedBytes = args.BytesTransferred;
+ receiveToken.CompletionSource.SetResult(result);
- args.SetBuffer(receivedBytes, expectedBytes - receivedBytes);
+ TransmissionArgsPool.Return(args);
+ }
+ else if (expectedBytes > args.BytesTransferred && args.BytesTransferred > 0)
+ {
+ // receive the remaining parts of the buffer
- Connection.ReceiveAsync(args);
- }
- else
- {
- // no bytes were received, remote socket is dead
+ int receivedBytes = args.BytesTransferred;
- receiveToken.CompletionSource.SetException(new SocketException((int)SocketError.HostDown));
+ args.SetBuffer(receivedBytes, expectedBytes - receivedBytes);
- TransmissionArgsPool.Return(args);
- }
+ Connection.ReceiveAsync(args);
+ }
+ else
+ {
+ // no bytes were received, remote socket is dead
- break;
+ receiveToken.CompletionSource.SetException(new SocketException((int)SocketError.HostDown));
- case SocketError.OperationAborted:
- Debug.WriteLine("CompleteReceive experienced SocketError.OperationAborted!");
+ TransmissionArgsPool.Return(args);
+ }
- receiveToken.CompletionSource.SetResult(TransmissionResult.Timeout);
+ break;
- TransmissionArgsPool.Return(args);
+ case SocketError.OperationAborted:
+ TransmissionArgsPool.Return(args);
- break;
+ break;
- default:
- receiveToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+ default:
+ receiveToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
- TransmissionArgsPool.Return(args);
+ TransmissionArgsPool.Return(args);
- break;
+ break;
+ }
}
}
@@ -173,58 +170,57 @@ namespace NetSharp.Sockets.Stream
{
AsyncTransmissionToken sendToken = (AsyncTransmissionToken)args.UserToken;
- switch (args.SocketError)
+ if (!sendToken.CancellationToken.IsCancellationRequested)
{
- case SocketError.Success:
- Memory<byte> transmissionBuffer = args.MemoryBuffer;
- int remainingBytes = transmissionBuffer.Length;
-
- if (args.BytesTransferred == remainingBytes)
- {
- // buffer was fully sent
+ switch (args.SocketError)
+ {
+ case SocketError.Success:
+ Memory<byte> transmissionBuffer = args.MemoryBuffer;
+ int remainingBytes = transmissionBuffer.Length;
- TransmissionResult result = new TransmissionResult(in args);
+ if (args.BytesTransferred == remainingBytes)
+ {
+ // buffer was fully sent
- sendToken.CompletionSource.SetResult(result);
-
- TransmissionArgsPool.Return(args);
- }
- else if (remainingBytes > args.BytesTransferred && args.BytesTransferred > 0)
- {
- // send the remaining parts of the buffer
+ TransmissionResult result = new TransmissionResult(in args);
- int sentBytes = args.BytesTransferred;
+ sendToken.CompletionSource.SetResult(result);
- args.SetBuffer(sentBytes, remainingBytes - sentBytes);
+ TransmissionArgsPool.Return(args);
+ }
+ else if (remainingBytes > args.BytesTransferred && args.BytesTransferred > 0)
+ {
+ // send the remaining parts of the buffer
- Connection.SendAsync(args);
- }
- else
- {
- // no bytes were sent, remote socket is dead
+ int sentBytes = args.BytesTransferred;
- sendToken.CompletionSource.SetException(new SocketException((int)SocketError.HostDown));
+ args.SetBuffer(sentBytes, remainingBytes - sentBytes);
- TransmissionArgsPool.Return(args);
- }
+ Connection.SendAsync(args);
+ }
+ else
+ {
+ // no bytes were sent, remote socket is dead
- break;
+ sendToken.CompletionSource.SetException(new SocketException((int)SocketError.HostDown));
- case SocketError.OperationAborted:
- Debug.WriteLine("CompleteSend experienced SocketError.OperationAborted!");
+ TransmissionArgsPool.Return(args);
+ }
- sendToken.CompletionSource.SetResult(TransmissionResult.Timeout);
+ break;
- TransmissionArgsPool.Return(args);
+ case SocketError.OperationAborted:
+ TransmissionArgsPool.Return(args);
- break;
+ break;
- default:
- sendToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
+ default:
+ sendToken.CompletionSource.SetException(new SocketException((int)args.SocketError));
- TransmissionArgsPool.Return(args);
+ TransmissionArgsPool.Return(args);
- break;
+ break;
+ }
}
}
@@ -299,12 +295,23 @@ namespace NetSharp.Sockets.Stream
SocketAsyncEventArgs args = TransmissionArgsPool.Rent();
args.DisconnectReuseSocket = allowSocketReuse;
- args.UserToken = new AsyncOperationToken(in tcs, in cancellationToken);
+ args.UserToken = new AsyncOperationToken(in tcs, CancellationToken.None);
+
+ // TODO find out why the fricc we leak memory
+ CancellationTokenRegistration cancellationRegistration =
+ cancellationToken.Register(CancelAsyncTransmissionCallback, args.UserToken);
- //TODO implement cancellation for client socket disconnectAsync
- //cancellationToken.Register();
+ if (Connection.DisconnectAsync(args))
+ return new ValueTask(
+ tcs.Task.ContinueWith((task, state) =>
+ {
+ ((CancellationTokenRegistration)state).Dispose();
+
+ return task.Result;
+ }, cancellationRegistration, CancellationToken.None)
+ );
- if (Connection.DisconnectAsync(args)) return new ValueTask(tcs.Task);
+ cancellationRegistration.Dispose();
TransmissionArgsPool.Return(args);
@@ -324,8 +331,7 @@ namespace NetSharp.Sockets.Stream
return new TransmissionResult(in buffer, in receivedBytes, Connection.RemoteEndPoint);
}
- public ValueTask<TransmissionResult> ReceiveAsync(Memory<byte> receiveBuffer, SocketFlags flags = SocketFlags.None,
- CancellationToken cancellationToken = default)
+ public ValueTask<TransmissionResult> ReceiveAsync(Memory<byte> receiveBuffer, SocketFlags flags = SocketFlags.None, CancellationToken cancellationToken = default)
{
TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
@@ -334,12 +340,23 @@ namespace NetSharp.Sockets.Stream
args.SetBuffer(receiveBuffer);
args.SocketFlags = flags;
- args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken);
+ args.UserToken = new AsyncTransmissionToken(in tcs, in args, CancellationToken.None);
- // TODO implement cancellation for client socket receiveAsync
- cancellationToken.Register(CancelAsyncTransmissionCallback, new object());
+ // TODO find out why the fricc we leak memory
+ CancellationTokenRegistration cancellationRegistration =
+ cancellationToken.Register(CancelAsyncTransmissionCallback, args.UserToken);
- if (Connection.ReceiveAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task);
+ if (Connection.ReceiveAsync(args))
+ return new ValueTask<TransmissionResult>(
+ tcs.Task.ContinueWith((task, state) =>
+ {
+ ((CancellationTokenRegistration)state).Dispose();
+
+ return task.Result;
+ }, cancellationRegistration, CancellationToken.None)
+ );
+
+ cancellationRegistration.Dispose();
TransmissionResult result = new TransmissionResult(in args);
@@ -361,8 +378,7 @@ namespace NetSharp.Sockets.Stream
return new TransmissionResult(in buffer, in sentBytes, Connection.RemoteEndPoint);
}
- public ValueTask<TransmissionResult> SendAsync(Memory<byte> sendBuffer, SocketFlags flags = SocketFlags.None,
- CancellationToken cancellationToken = default)
+ public ValueTask<TransmissionResult> SendAsync(Memory<byte> sendBuffer, SocketFlags flags = SocketFlags.None, CancellationToken cancellationToken = default)
{
TaskCompletionSource<TransmissionResult> tcs = new TaskCompletionSource<TransmissionResult>();
@@ -371,12 +387,23 @@ namespace NetSharp.Sockets.Stream
args.SetBuffer(sendBuffer);
args.SocketFlags = flags;
- args.UserToken = new AsyncTransmissionToken(in tcs, in cancellationToken);
+ args.UserToken = new AsyncTransmissionToken(in tcs, in args, CancellationToken.None);
+
+ // TODO find out why the fricc we leak memory
+ CancellationTokenRegistration cancellationRegistration =
+ cancellationToken.Register(CancelAsyncTransmissionCallback, args.UserToken);
+
+ if (Connection.SendToAsync(args))
+ return new ValueTask<TransmissionResult>(
+ tcs.Task.ContinueWith((task, state) =>
+ {
+ ((CancellationTokenRegistration)state).Dispose();
- // TODO implement cancellation for client socket sendAsync
- cancellationToken.Register(CancelAsyncTransmissionCallback, new object());
+ return task.Result;
+ }, cancellationRegistration, CancellationToken.None)
+ );
- if (Connection.SendAsync(args)) return new ValueTask<TransmissionResult>(tcs.Task);
+ cancellationRegistration.Dispose();
TransmissionResult result = new TransmissionResult(in args);
diff --git a/NetSharp/NetSharpExamples/Benchmarks/UdpSocketClientAsyncBenchmark.cs b/NetSharp/NetSharpExamples/Benchmarks/UdpSocketClientAsyncBenchmark.cs
@@ -55,7 +55,7 @@ namespace NetSharpExamples.Benchmarks
Console.WriteLine($"{PacketCount} packets will be sent per client. This could take a long time (maybe more than a minute)!");
}
- using CancellationTokenSource serverCts = new CancellationTokenSource();
+ using CancellationTokenSource serverCts = new CancellationTokenSource(); serverCts.Cancel();
Task serverTask = Task.Factory.StartNew(state => ServerTask((CancellationToken)state), serverCts.Token, TaskCreationOptions.LongRunning);
BenchmarkHelper benchmarkHelper = new BenchmarkHelper();
@@ -85,15 +85,6 @@ namespace NetSharpExamples.Benchmarks
benchmarkHelper.PrintBandwidthStats(0, PacketCount, NetworkPacket.TotalSize);
benchmarkHelper.PrintRttStats(0);
-
- serverCts.Cancel();
- try
- {
- serverTask.Dispose();
- }
- catch (Exception) { }
-
- Console.WriteLine($"UDP Client Benchmark finished!");
}
}
}
\ No newline at end of file
diff --git a/NetSharp/NetSharpExamples/Examples/UdpSocketClientCancellationExample.cs b/NetSharp/NetSharpExamples/Examples/UdpSocketClientCancellationExample.cs
@@ -20,7 +20,7 @@ namespace NetSharpExamples.Examples
/// <summary>
/// A read only server. Never sends out data!
/// </summary>
- private Task ServerTask(CancellationToken cancellationToken)
+ private Task ServerTask()
{
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
@@ -30,12 +30,18 @@ namespace NetSharpExamples.Examples
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
- while (!cancellationToken.IsCancellationRequested)
+ for (int i = 0; i < 10; i++)
{
server.ReceiveFrom(transmissionBuffer, ref remoteEndPoint);
}
+ for (int i = 0; i < 9; i++)
+ {
+ server.SendTo(transmissionBuffer, remoteEndPoint);
+ }
+
server.Close();
+ server.Dispose();
return Task.CompletedTask;
}
@@ -43,11 +49,10 @@ namespace NetSharpExamples.Examples
/// <inheritdoc />
public async Task RunAsync()
{
- using CancellationTokenSource serverCts = new CancellationTokenSource();
- Task serverTask = Task.Factory.StartNew(state => ServerTask((CancellationToken)state), serverCts.Token, TaskCreationOptions.LongRunning);
+ Task serverTask = Task.Factory.StartNew(ServerTask, TaskCreationOptions.LongRunning);
DatagramSocketClientOptions clientOptions = new DatagramSocketClientOptions((ushort)2);
- using DatagramSocketClient client = new DatagramSocketClient(AddressFamily.InterNetwork, ProtocolType.Udp, clientOptions);
+ DatagramSocketClient client = new DatagramSocketClient(AddressFamily.InterNetwork, ProtocolType.Udp, clientOptions);
byte[] sendBuffer = new byte[NetworkPacket.TotalSize];
byte[] receiveBuffer = new byte[NetworkPacket.TotalSize];
@@ -60,7 +65,8 @@ namespace NetSharpExamples.Examples
for (int i = 0; i < 10; i++)
{
- CancellationTokenSource sendCts = new CancellationTokenSource();
+ using CancellationTokenSource sendCts = new CancellationTokenSource();
+ using CancellationTokenSource receiveCts = new CancellationTokenSource();
sendCts.CancelAfter(timeout);
TransmissionResult sendResult = await client.SendToAsync(remoteEndPoint, sendBuffer, SocketFlags.None, sendCts.Token);
@@ -68,26 +74,28 @@ namespace NetSharpExamples.Examples
if (sendResult.TimedOut())
{
Console.WriteLine("Send timed out!");
-
- continue;
}
-
- Console.WriteLine($"Sent {sendResult.Count} bytes of data!");
-
- CancellationTokenSource receiveCts = new CancellationTokenSource();
-
- receiveCts.CancelAfter(timeout);
- TransmissionResult receiveResult = await client.ReceiveFromAsync(remoteEndPoint, receiveBuffer, SocketFlags.None, receiveCts.Token);
-
- if (receiveResult.TimedOut())
+ else
{
- Console.WriteLine("Receive timed out!");
-
- continue;
+ Console.WriteLine($"Sent {sendResult.Count} bytes of data!");
+
+ receiveCts.CancelAfter(timeout);
+ TransmissionResult receiveResult = await client.ReceiveFromAsync(remoteEndPoint, receiveBuffer, SocketFlags.None, receiveCts.Token);
+
+ if (receiveResult.TimedOut())
+ {
+ Console.WriteLine("Receive timed out!");
+ }
+ else
+ {
+ Console.WriteLine($"Received {receiveResult.Count} bytes of data!");
+ }
}
-
- Console.WriteLine($"Received {receiveResult.Count} bytes of data!");
}
+
+ client.Dispose();
+
+ Console.WriteLine($"UDP Socket Client finished!");
}
}
}
\ No newline at end of file
diff --git a/NetSharp/NetSharpExamples/NetSharpExamples.xml b/NetSharp/NetSharpExamples/NetSharpExamples.xml
@@ -85,7 +85,7 @@
<member name="P:NetSharpExamples.Examples.UdpSocketClientCancellationExample.Name">
<inheritdoc />
</member>
- <member name="M:NetSharpExamples.Examples.UdpSocketClientCancellationExample.ServerTask(System.Threading.CancellationToken)">
+ <member name="M:NetSharpExamples.Examples.UdpSocketClientCancellationExample.ServerTask">
<summary>
A read only server. Never sends out data!
</summary>
diff --git a/NetSharp/NetSharpExamples/Program.cs b/NetSharp/NetSharpExamples/Program.cs
@@ -16,7 +16,7 @@ namespace NetSharpExamples
new UdpSocketClientSyncBenchmark(),
new UdpSocketClientAsyncBenchmark(),
new UdpSocketClientExample(),
- //new UdpSocketClientCancellationExample(), // TODO make functional
+ new UdpSocketClientCancellationExample(), // TODO make functional
// TCP socket server and client examples
new TcpSocketServerBenchmark(),