HubConnection implements IAsyncDisposable (#13179)

This commit is contained in:
Brennan 2019-08-19 09:36:43 -07:00 committed by GitHub
parent 7118601f4c
commit 8987cca7c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 9 deletions

View File

@ -3,7 +3,7 @@
namespace Microsoft.AspNetCore.SignalR.Client namespace Microsoft.AspNetCore.SignalR.Client
{ {
public partial class HubConnection public partial class HubConnection : System.IAsyncDisposable
{ {
public static readonly System.TimeSpan DefaultHandshakeTimeout; public static readonly System.TimeSpan DefaultHandshakeTimeout;
public static readonly System.TimeSpan DefaultKeepAliveInterval; public static readonly System.TimeSpan DefaultKeepAliveInterval;
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
public event System.Func<string, System.Threading.Tasks.Task> Reconnected { add { } remove { } } public event System.Func<string, System.Threading.Tasks.Task> Reconnected { add { } remove { } }
public event System.Func<System.Exception, System.Threading.Tasks.Task> Reconnecting { add { } remove { } } public event System.Func<System.Exception, System.Threading.Tasks.Task> Reconnecting { add { } remove { } }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task DisposeAsync() { throw null; } public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task<object> InvokeCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public System.Threading.Tasks.Task<object> InvokeCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.IDisposable On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) { throw null; } public System.IDisposable On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) { throw null; }

View File

@ -3,7 +3,7 @@
namespace Microsoft.AspNetCore.SignalR.Client namespace Microsoft.AspNetCore.SignalR.Client
{ {
public partial class HubConnection public partial class HubConnection : System.IAsyncDisposable
{ {
public static readonly System.TimeSpan DefaultHandshakeTimeout; public static readonly System.TimeSpan DefaultHandshakeTimeout;
public static readonly System.TimeSpan DefaultKeepAliveInterval; public static readonly System.TimeSpan DefaultKeepAliveInterval;
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
public event System.Func<string, System.Threading.Tasks.Task> Reconnected { add { } remove { } } public event System.Func<string, System.Threading.Tasks.Task> Reconnected { add { } remove { } }
public event System.Func<System.Exception, System.Threading.Tasks.Task> Reconnecting { add { } remove { } } public event System.Func<System.Exception, System.Threading.Tasks.Task> Reconnecting { add { } remove { } }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task DisposeAsync() { throw null; } public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public System.Threading.Tasks.Task<object> InvokeCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public System.Threading.Tasks.Task<object> InvokeCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public System.IDisposable On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) { throw null; } public System.IDisposable On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) { throw null; }

View File

@ -22,7 +22,6 @@ using Microsoft.AspNetCore.SignalR.Internal;
using Microsoft.AspNetCore.SignalR.Protocol; using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.SignalR.Client namespace Microsoft.AspNetCore.SignalR.Client
{ {
@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.SignalR.Client
/// Before hub methods can be invoked the connection must be started using <see cref="StartAsync"/>. /// Before hub methods can be invoked the connection must be started using <see cref="StartAsync"/>.
/// Clean up a connection using <see cref="StopAsync"/> or <see cref="DisposeAsync"/>. /// Clean up a connection using <see cref="StopAsync"/> or <see cref="DisposeAsync"/>.
/// </remarks> /// </remarks>
public partial class HubConnection public partial class HubConnection : IAsyncDisposable
{ {
public static readonly TimeSpan DefaultServerTimeout = TimeSpan.FromSeconds(30); // Server ping rate is 15 sec, this is 2 times that. public static readonly TimeSpan DefaultServerTimeout = TimeSpan.FromSeconds(30); // Server ping rate is 15 sec, this is 2 times that.
public static readonly TimeSpan DefaultHandshakeTimeout = TimeSpan.FromSeconds(15); public static readonly TimeSpan DefaultHandshakeTimeout = TimeSpan.FromSeconds(15);
@ -292,8 +291,8 @@ namespace Microsoft.AspNetCore.SignalR.Client
/// <summary> /// <summary>
/// Disposes the <see cref="HubConnection"/>. /// Disposes the <see cref="HubConnection"/>.
/// </summary> /// </summary>
/// <returns>A <see cref="Task"/> that represents the asynchronous dispose.</returns> /// <returns>A <see cref="ValueTask"/> that represents the asynchronous dispose.</returns>
public async Task DisposeAsync() public async ValueTask DisposeAsync()
{ {
if (!_disposed) if (!_disposed)
{ {
@ -504,8 +503,16 @@ namespace Microsoft.AspNetCore.SignalR.Client
if (disposing) if (disposing)
{ {
(_serviceProvider as IDisposable)?.Dispose(); // Must set this before calling DisposeAsync because the service provider has a reference to the HubConnection and will try to dispose it again
_disposed = true; _disposed = true;
if (_serviceProvider is IAsyncDisposable asyncDispose)
{
await asyncDispose.DisposeAsync();
}
else
{
(_serviceProvider as IDisposable)?.Dispose();
}
} }
} }
finally finally

View File

@ -414,6 +414,17 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests
} }
} }
[Fact]
public async Task CanAwaitUsingHubConnection()
{
using (StartVerifiableLog())
{
var connection = new TestConnection();
await using var hubConnection = CreateHubConnection(connection, loggerFactory: LoggerFactory);
await hubConnection.StartAsync().OrTimeout();
}
}
private class SampleObject private class SampleObject
{ {
public SampleObject(string foo, int bar) public SampleObject(string foo, int bar)