feature: Implement Dispose for types which have disposable data (#1171)

* Initial set of dispose implementations

Not handled yet:
- Discord.Net.Websocket/Entities/SocketGuild
- Discord.Net.Tests

* Refactor DiscordSocketClient init into ctor

This way we remove an IDisposableAnalyzer warning for not disposing
the client when we set the client variable.

* Dispose of clients when disposing sharded client

* Finish implementing IDisposable where appropriate

I opted to use NoWarn in the Tests project as it wasn't really necessary
considering that our tests only run once

* Tweak samples after feedback
This commit is contained in:
Monica S
2018-11-29 01:18:16 +00:00
committed by Christopher F
parent dca6c33da3
commit 7366cd4361
31 changed files with 406 additions and 154 deletions

View File

@@ -43,6 +43,8 @@ namespace Discord.WebSocket
private DateTimeOffset? _statusSince;
private RestApplication _applicationInfo;
private bool _isDisposed;
/// <summary> Gets the shard of of this client. </summary>
public int ShardId { get; }
/// <summary> Gets the current connection state of this client. </summary>
@@ -63,7 +65,7 @@ namespace Discord.WebSocket
internal WebSocketProvider WebSocketProvider { get; private set; }
internal bool AlwaysDownloadUsers { get; private set; }
internal int? HandlerTimeout { get; private set; }
internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
/// <inheritdoc />
public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds;
@@ -110,8 +112,10 @@ namespace Discord.WebSocket
/// Initializes a new REST/WebSocket-based Discord client with the provided configuration.
/// </summary>
/// <param name="config">The configuration to be used with the client.</param>
#pragma warning disable IDISP004
public DiscordSocketClient(DiscordSocketConfig config) : this(config, CreateApiClient(config), null, null) { }
internal DiscordSocketClient(DiscordSocketConfig config, SemaphoreSlim groupLock, DiscordSocketClient parentClient) : this(config, CreateApiClient(config), groupLock, parentClient) { }
#pragma warning restore IDISP004
private DiscordSocketClient(DiscordSocketConfig config, API.DiscordSocketApiClient client, SemaphoreSlim groupLock, DiscordSocketClient parentClient)
: base(config, client)
{
@@ -170,11 +174,18 @@ namespace Discord.WebSocket
/// <inheritdoc />
internal override void Dispose(bool disposing)
{
if (disposing)
if (!_isDisposed)
{
StopAsync().GetAwaiter().GetResult();
ApiClient.Dispose();
if (disposing)
{
StopAsync().GetAwaiter().GetResult();
ApiClient?.Dispose();
_stateLock?.Dispose();
}
_isDisposed = true;
}
base.Dispose(disposing);
}
/// <inheritdoc />
@@ -197,10 +208,10 @@ namespace Discord.WebSocket
}
/// <inheritdoc />
public override async Task StartAsync()
public override async Task StartAsync()
=> await _connection.StartAsync().ConfigureAwait(false);
/// <inheritdoc />
public override async Task StopAsync()
public override async Task StopAsync()
=> await _connection.StopAsync().ConfigureAwait(false);
private async Task OnConnectingAsync()
@@ -704,6 +715,7 @@ namespace Discord.WebSocket
{
await GuildUnavailableAsync(guild).ConfigureAwait(false);
await TimedInvokeAsync(_leftGuildEvent, nameof(LeftGuild), guild).ConfigureAwait(false);
(guild as IDisposable).Dispose();
}
else
{