diff --git a/.nuget/nuget.exe b/.nuget/nuget.exe
new file mode 100644
index 00000000..94aada9c
Binary files /dev/null and b/.nuget/nuget.exe differ
diff --git a/src/Lime.Client.Windows/Lime.Client.Windows.csproj b/src/Lime.Client.Windows/Lime.Client.Windows.csproj
index cdff6105..371979e9 100644
--- a/src/Lime.Client.Windows/Lime.Client.Windows.csproj
+++ b/src/Lime.Client.Windows/Lime.Client.Windows.csproj
@@ -111,8 +111,8 @@
..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll
True
-
- ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
True
diff --git a/src/Lime.Client.Windows/packages.config b/src/Lime.Client.Windows/packages.config
index 74108f74..2f6cdb99 100644
--- a/src/Lime.Client.Windows/packages.config
+++ b/src/Lime.Client.Windows/packages.config
@@ -10,7 +10,7 @@
-
+
diff --git a/src/Lime.Protocol/Listeners/BufferedChannelListener.cs b/src/Lime.Protocol/Listeners/BufferedChannelListener.cs
index 42625091..b1bdf7d7 100644
--- a/src/Lime.Protocol/Listeners/BufferedChannelListener.cs
+++ b/src/Lime.Protocol/Listeners/BufferedChannelListener.cs
@@ -50,6 +50,8 @@ public void Start(IEstablishedReceiverChannel channel)
{
throw new InvalidOperationException("The listener is already active");
}
+ // Dispose the previous cancelled CTS before creating a new one.
+ _cts?.Dispose();
_cts = new CancellationTokenSource();
MessageListenerTask = CreateListenerTask(
@@ -81,7 +83,7 @@ public void Stop()
throw new InvalidOperationException("The listener is not active");
}
- _cts.Cancel();
+ _cts.Cancel();
MessageBuffer.Writer.TryComplete();
NotificationBuffer.Writer.TryComplete();
CommandBuffer.Writer.TryComplete();
diff --git a/src/Lime.Protocol/Network/ChannelBase.cs b/src/Lime.Protocol/Network/ChannelBase.cs
index 44e2bfba..11b6edaa 100644
--- a/src/Lime.Protocol/Network/ChannelBase.cs
+++ b/src/Lime.Protocol/Network/ChannelBase.cs
@@ -378,6 +378,7 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
+ Transport.Closing -= Transport_Closing;
_receiverChannel.Dispose();
_senderChannel.Dispose();
Transport.DisposeIfDisposable();
diff --git a/src/Lime.Protocol/Network/EnvelopePipe.cs b/src/Lime.Protocol/Network/EnvelopePipe.cs
index fd6c32a1..e0034076 100644
--- a/src/Lime.Protocol/Network/EnvelopePipe.cs
+++ b/src/Lime.Protocol/Network/EnvelopePipe.cs
@@ -193,6 +193,7 @@ public async Task ReceiveAsync(CancellationToken cancellationToken)
public void Dispose()
{
_pipeCts.Dispose();
+ _semaphore.Dispose();
}
private Task TraceAsync(string data, DataOperation operation)
diff --git a/src/Lime.Protocol/Network/SynchronizedTransportDecorator.cs b/src/Lime.Protocol/Network/SynchronizedTransportDecorator.cs
index 4819189d..48418b22 100644
--- a/src/Lime.Protocol/Network/SynchronizedTransportDecorator.cs
+++ b/src/Lime.Protocol/Network/SynchronizedTransportDecorator.cs
@@ -8,7 +8,7 @@ namespace Lime.Protocol.Network
///
/// Defines a decorator for that synchronizes concurrent and calls.
///
- public sealed class SynchronizedTransportDecorator : ITransport
+ public sealed class SynchronizedTransportDecorator : ITransport, IDisposable
{
private readonly ITransport _transport;
private readonly SemaphoreSlim _sendSemaphore;
@@ -105,5 +105,11 @@ public event EventHandler Closed
add => _transport.Closed += value;
remove => _transport.Closed -= value;
}
+
+ public void Dispose()
+ {
+ _sendSemaphore.Dispose();
+ _receiveSemaphore.Dispose();
+ }
}
}
\ No newline at end of file
diff --git a/src/Lime.Protocol/Network/TransportBase.cs b/src/Lime.Protocol/Network/TransportBase.cs
index 960dd3bf..65f8c1d2 100644
--- a/src/Lime.Protocol/Network/TransportBase.cs
+++ b/src/Lime.Protocol/Network/TransportBase.cs
@@ -9,7 +9,7 @@ namespace Lime.Protocol.Network
///
/// Base class for transport implementation.
///
- public abstract class TransportBase : ITransport
+ public abstract class TransportBase : ITransport, IDisposable
{
private bool _isOpen; // TODO: Merge this logic with IsConnected
private bool _closingInvoked;
@@ -239,5 +239,26 @@ protected virtual void OnClosed()
Closed.RaiseEvent(this, EventArgs.Empty);
}
}
+
+ ///
+ /// Releases resources used by this transport instance.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases managed and - optionally - unmanaged resources.
+ ///
+ /// true to release managed resources.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _openCloseSemaphore.Dispose();
+ }
+ }
}
}
diff --git a/src/Lime.Transport.AspNetCore/Transport/HttpContextChannel.cs b/src/Lime.Transport.AspNetCore/Transport/HttpContextChannel.cs
index d3d52117..a3620e73 100644
--- a/src/Lime.Transport.AspNetCore/Transport/HttpContextChannel.cs
+++ b/src/Lime.Transport.AspNetCore/Transport/HttpContextChannel.cs
@@ -14,7 +14,7 @@ namespace Lime.Transport.AspNetCore.Transport
///
/// Emulates a channel using the HttpContext to allow the application sending a envelope in the HTTP response.
///
- internal sealed class HttpContextChannel : ISenderChannel
+ internal sealed class HttpContextChannel : ISenderChannel, IDisposable
{
private readonly HttpContext _context;
private readonly IEnvelopeSerializer _envelopeSerializer;
@@ -98,5 +98,10 @@ private void EnsureNotSent()
throw new NotSupportedException("Only one envelope can be sent per request on HTTP transport");
}
}
+
+ public void Dispose()
+ {
+ _sendSemaphore.Dispose();
+ }
}
}
\ No newline at end of file
diff --git a/src/Lime.Transport.Redis/RedisTransport.cs b/src/Lime.Transport.Redis/RedisTransport.cs
index f45f0522..ad155c35 100644
--- a/src/Lime.Transport.Redis/RedisTransport.cs
+++ b/src/Lime.Transport.Redis/RedisTransport.cs
@@ -268,6 +268,8 @@ protected virtual void Dispose(bool disposing)
{
_connectionMultiplexer.Dispose();
}
+ _semaphore.Dispose();
+ base.Dispose(disposing);
}
}
diff --git a/src/Lime.Transport.Redis/RedisTransportListener.cs b/src/Lime.Transport.Redis/RedisTransportListener.cs
index 0bb6273e..00b040dc 100644
--- a/src/Lime.Transport.Redis/RedisTransportListener.cs
+++ b/src/Lime.Transport.Redis/RedisTransportListener.cs
@@ -158,6 +158,7 @@ private void HandleReceivedData(RedisChannel channel, RedisValue value)
public void Dispose()
{
_connectionMultiplexer?.Dispose();
+ _semaphore.Dispose();
}
}
}
diff --git a/src/Lime.Transport.Tcp/PipeTcpTransport.cs b/src/Lime.Transport.Tcp/PipeTcpTransport.cs
index c0342de4..62edb263 100644
--- a/src/Lime.Transport.Tcp/PipeTcpTransport.cs
+++ b/src/Lime.Transport.Tcp/PipeTcpTransport.cs
@@ -467,6 +467,7 @@ protected override Task PerformCloseAsync(CancellationToken cancellationToken)
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
@@ -478,6 +479,7 @@ protected virtual void Dispose(bool disposing)
_optionsSemaphore.Dispose();
_stream?.Dispose();
_envelopePipe.Dispose();
+ base.Dispose(disposing);
}
_disposed = true;
@@ -566,11 +568,11 @@ private bool ValidateClientCertificate(
return sslPolicyErrors == SslPolicyErrors.None;
}
- private Task CloseWithTimeoutAsync()
+ private async Task CloseWithTimeoutAsync()
{
using (var cts = new CancellationTokenSource(CloseTimeout))
{
- return CloseAsync(cts.Token);
+ await CloseAsync(cts.Token).ConfigureAwait(false);
}
}
}
diff --git a/src/Lime.Transport.Tcp/PipeTcpTransportListener.cs b/src/Lime.Transport.Tcp/PipeTcpTransportListener.cs
index 77ec9ce1..b519f46f 100644
--- a/src/Lime.Transport.Tcp/PipeTcpTransportListener.cs
+++ b/src/Lime.Transport.Tcp/PipeTcpTransportListener.cs
@@ -14,7 +14,7 @@
namespace Lime.Transport.Tcp
{
- public class PipeTcpTransportListener : ITransportListener
+ public class PipeTcpTransportListener : ITransportListener, IDisposable
{
private readonly X509Certificate2 _serverCertificate;
private readonly IEnvelopeSerializer _envelopeSerializer;
@@ -181,5 +181,10 @@ public async Task StopAsync(CancellationToken cancellationToken)
_semaphore.Release();
}
}
+
+ public void Dispose()
+ {
+ _semaphore.Dispose();
+ }
}
}
diff --git a/src/Lime.Transport.Tcp/TcpTransport.cs b/src/Lime.Transport.Tcp/TcpTransport.cs
index b5ca6a2a..b227e33f 100644
--- a/src/Lime.Transport.Tcp/TcpTransport.cs
+++ b/src/Lime.Transport.Tcp/TcpTransport.cs
@@ -581,6 +581,7 @@ protected override Task PerformCloseAsync(CancellationToken cancellationToken)
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
@@ -592,6 +593,7 @@ protected virtual void Dispose(bool disposing)
_optionsSemaphore.Dispose();
_stream?.Dispose();
_jsonBuffer.Dispose();
+ base.Dispose(disposing);
}
_disposed = true;
@@ -640,11 +642,11 @@ private bool ValidateClientCertificate(
private bool CanRead => _stream != null && _stream.CanRead && _tcpClient.Connected;
- private Task CloseWithTimeoutAsync()
+ private async Task CloseWithTimeoutAsync()
{
using (var cts = new CancellationTokenSource(CloseTimeout))
{
- return CloseAsync(cts.Token);
+ await CloseAsync(cts.Token).ConfigureAwait(false);
}
}
diff --git a/src/Lime.Transport.Tcp/TcpTransportListener.cs b/src/Lime.Transport.Tcp/TcpTransportListener.cs
index 0c5989b8..de3f9ca1 100644
--- a/src/Lime.Transport.Tcp/TcpTransportListener.cs
+++ b/src/Lime.Transport.Tcp/TcpTransportListener.cs
@@ -14,7 +14,7 @@
namespace Lime.Transport.Tcp
{
- public class TcpTransportListener : ITransportListener
+ public class TcpTransportListener : ITransportListener, IDisposable
{
private readonly X509Certificate2 _serverCertificate;
private readonly IEnvelopeSerializer _envelopeSerializer;
@@ -189,5 +189,10 @@ public async Task StopAsync(CancellationToken cancellationToken)
_semaphore.Release();
}
}
+
+ public void Dispose()
+ {
+ _semaphore.Dispose();
+ }
}
}
diff --git a/src/Lime.Transport.WebSocket/PipeWebSocketTransport.cs b/src/Lime.Transport.WebSocket/PipeWebSocketTransport.cs
index aef7bf43..01798179 100644
--- a/src/Lime.Transport.WebSocket/PipeWebSocketTransport.cs
+++ b/src/Lime.Transport.WebSocket/PipeWebSocketTransport.cs
@@ -191,6 +191,7 @@ protected virtual void Dispose(bool disposing)
WebSocket.Dispose();
_envelopePipe.Dispose();
_closeSemaphore.Dispose();
+ base.Dispose(disposing);
}
}
@@ -241,11 +242,11 @@ private void HandleCloseMessage(ValueWebSocketReceiveResult receiveResult)
_closeStatus = WebSocketCloseStatus.NormalClosure;
}
- private Task CloseWithTimeoutAsync()
+ private async Task CloseWithTimeoutAsync()
{
using (var cts = new CancellationTokenSource(CloseTimeout))
{
- return CloseAsync(cts.Token);
+ await CloseAsync(cts.Token).ConfigureAwait(false);
}
}
}
diff --git a/src/Lime.Transport.WebSocket/WebSocketTransport.cs b/src/Lime.Transport.WebSocket/WebSocketTransport.cs
index 763242b3..10e681c2 100644
--- a/src/Lime.Transport.WebSocket/WebSocketTransport.cs
+++ b/src/Lime.Transport.WebSocket/WebSocketTransport.cs
@@ -327,6 +327,7 @@ protected virtual void Dispose(bool disposing)
WebSocket.Dispose();
_closeSemaphore.Dispose();
_sendReceiveCts.Dispose();
+ base.Dispose(disposing);
}
}
@@ -343,11 +344,11 @@ private void HandleCloseMessage(WebSocketReceiveResult receiveResult)
CloseStatus = WebSocketCloseStatus.NormalClosure;
}
- private Task CloseWithTimeoutAsync()
+ private async Task CloseWithTimeoutAsync()
{
using (var cts = new CancellationTokenSource(CloseTimeout))
{
- return CloseAsync(cts.Token);
+ await CloseAsync(cts.Token).ConfigureAwait(false);
}
}