mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-25 23:53:07 +08:00
Elide repeated Action-delegate allocation by caching it (#1324)
* Elide repeated Action-delegate allocation by caching it Here C# compiler has too little knowledge about the usage of the delegate, we know better so cache it on our own to avoid the repeated allocation. * Use conditional compilation
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
@@ -11,12 +11,14 @@ namespace MQTTnet.Implementations
|
|||||||
public sealed class CrossPlatformSocket : IDisposable
|
public sealed class CrossPlatformSocket : IDisposable
|
||||||
{
|
{
|
||||||
readonly Socket _socket;
|
readonly Socket _socket;
|
||||||
|
readonly Action _socketDisposeAction;
|
||||||
|
|
||||||
NetworkStream _networkStream;
|
NetworkStream _networkStream;
|
||||||
|
|
||||||
public CrossPlatformSocket(AddressFamily addressFamily)
|
public CrossPlatformSocket(AddressFamily addressFamily)
|
||||||
{
|
{
|
||||||
_socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
|
_socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
_socketDisposeAction = _socket.Dispose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CrossPlatformSocket()
|
public CrossPlatformSocket()
|
||||||
@@ -24,12 +26,16 @@ namespace MQTTnet.Implementations
|
|||||||
// Having this constructor is important because avoiding the address family as parameter
|
// Having this constructor is important because avoiding the address family as parameter
|
||||||
// will make use of dual mode in the .net framework.
|
// will make use of dual mode in the .net framework.
|
||||||
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
|
||||||
|
_socketDisposeAction = _socket.Dispose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CrossPlatformSocket(Socket socket)
|
public CrossPlatformSocket(Socket socket)
|
||||||
{
|
{
|
||||||
_socket = socket ?? throw new ArgumentNullException(nameof(socket));
|
_socket = socket ?? throw new ArgumentNullException(nameof(socket));
|
||||||
_networkStream = new NetworkStream(socket, true);
|
_networkStream = new NetworkStream(socket, true);
|
||||||
|
|
||||||
|
_socketDisposeAction = _socket.Dispose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool NoDelay
|
public bool NoDelay
|
||||||
@@ -112,7 +118,7 @@ namespace MQTTnet.Implementations
|
|||||||
_networkStream?.Dispose();
|
_networkStream?.Dispose();
|
||||||
|
|
||||||
// Workaround for: https://github.com/dotnet/corefx/issues/24430
|
// Workaround for: https://github.com/dotnet/corefx/issues/24430
|
||||||
using (cancellationToken.Register(() => _socket.Dispose()))
|
using (cancellationToken.Register(_socketDisposeAction))
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,16 @@ namespace MQTTnet.Implementations
|
|||||||
{
|
{
|
||||||
readonly IMqttClientOptions _clientOptions;
|
readonly IMqttClientOptions _clientOptions;
|
||||||
readonly MqttClientTcpOptions _tcpOptions;
|
readonly MqttClientTcpOptions _tcpOptions;
|
||||||
|
readonly Action _disposeAction;
|
||||||
|
|
||||||
Stream _stream;
|
Stream _stream;
|
||||||
|
|
||||||
public MqttTcpChannel(IMqttClientOptions clientOptions)
|
public MqttTcpChannel()
|
||||||
|
{
|
||||||
|
_disposeAction = Dispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MqttTcpChannel(IMqttClientOptions clientOptions) : this()
|
||||||
{
|
{
|
||||||
_clientOptions = clientOptions ?? throw new ArgumentNullException(nameof(clientOptions));
|
_clientOptions = clientOptions ?? throw new ArgumentNullException(nameof(clientOptions));
|
||||||
_tcpOptions = (MqttClientTcpOptions)clientOptions.ChannelOptions;
|
_tcpOptions = (MqttClientTcpOptions)clientOptions.ChannelOptions;
|
||||||
@@ -29,7 +35,7 @@ namespace MQTTnet.Implementations
|
|||||||
IsSecureConnection = clientOptions.ChannelOptions?.TlsOptions?.UseTls == true;
|
IsSecureConnection = clientOptions.ChannelOptions?.TlsOptions?.UseTls == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MqttTcpChannel(Stream stream, string endpoint, X509Certificate2 clientCertificate)
|
public MqttTcpChannel(Stream stream, string endpoint, X509Certificate2 clientCertificate) : this()
|
||||||
{
|
{
|
||||||
_stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
_stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||||
|
|
||||||
@@ -149,11 +155,15 @@ namespace MQTTnet.Implementations
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
|
||||||
|
return await stream.ReadAsync(buffer.AsMemory(offset, count), cancellationToken).ConfigureAwait(false);
|
||||||
|
#else
|
||||||
// Workaround for: https://github.com/dotnet/corefx/issues/24430
|
// Workaround for: https://github.com/dotnet/corefx/issues/24430
|
||||||
using (cancellationToken.Register(Dispose))
|
using (cancellationToken.Register(_disposeAction))
|
||||||
{
|
{
|
||||||
return await stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
return await stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException)
|
catch (ObjectDisposedException)
|
||||||
{
|
{
|
||||||
@@ -177,18 +187,22 @@ namespace MQTTnet.Implementations
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Workaround for: https://github.com/dotnet/corefx/issues/24430
|
var stream = _stream;
|
||||||
using (cancellationToken.Register(Dispose))
|
|
||||||
|
if (stream == null)
|
||||||
{
|
{
|
||||||
var stream = _stream;
|
throw new MqttCommunicationException("The TCP connection is closed.");
|
||||||
|
}
|
||||||
if (stream == null)
|
|
||||||
{
|
|
||||||
throw new MqttCommunicationException("The TCP connection is closed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if NETCOREAPP3_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
|
||||||
|
await stream.WriteAsync(buffer.AsMemory(offset, count), cancellationToken).ConfigureAwait(false);
|
||||||
|
#else
|
||||||
|
// Workaround for: https://github.com/dotnet/corefx/issues/24430
|
||||||
|
using (cancellationToken.Register(_disposeAction))
|
||||||
|
{
|
||||||
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
catch (ObjectDisposedException)
|
catch (ObjectDisposedException)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user