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

@@ -18,7 +18,9 @@ namespace Discord.WebSocket
private int[] _shardIds;
private DiscordSocketClient[] _shards;
private int _totalShards;
private bool _isDisposed;
/// <inheritdoc />
public override int Latency { get => GetLatency(); protected set { } }
/// <inheritdoc />
@@ -38,11 +40,15 @@ namespace Discord.WebSocket
/// <summary> Creates a new REST/WebSocket Discord client. </summary>
public DiscordShardedClient() : this(null, new DiscordSocketConfig()) { }
/// <summary> Creates a new REST/WebSocket Discord client. </summary>
#pragma warning disable IDISP004
public DiscordShardedClient(DiscordSocketConfig config) : this(null, config, CreateApiClient(config)) { }
#pragma warning restore IDISP004
/// <summary> Creates a new REST/WebSocket Discord client. </summary>
public DiscordShardedClient(int[] ids) : this(ids, new DiscordSocketConfig()) { }
/// <summary> Creates a new REST/WebSocket Discord client. </summary>
#pragma warning disable IDISP004
public DiscordShardedClient(int[] ids, DiscordSocketConfig config) : this(ids, config, CreateApiClient(config)) { }
#pragma warning restore IDISP004
private DiscordShardedClient(int[] ids, DiscordSocketConfig config, API.DiscordSocketApiClient client)
: base(config, client)
{
@@ -119,10 +125,10 @@ namespace Discord.WebSocket
}
/// <inheritdoc />
public override async Task StartAsync()
public override async Task StartAsync()
=> await Task.WhenAll(_shards.Select(x => x.StartAsync())).ConfigureAwait(false);
/// <inheritdoc />
public override async Task StopAsync()
public override async Task StopAsync()
=> await Task.WhenAll(_shards.Select(x => x.StopAsync())).ConfigureAwait(false);
public DiscordSocketClient GetShard(int id)
@@ -145,7 +151,7 @@ namespace Discord.WebSocket
=> await _shards[0].GetApplicationInfoAsync(options).ConfigureAwait(false);
/// <inheritdoc />
public override SocketGuild GetGuild(ulong id)
public override SocketGuild GetGuild(ulong id)
=> GetShardFor(id).GetGuild(id);
/// <inheritdoc />
@@ -173,7 +179,7 @@ namespace Discord.WebSocket
for (int i = 0; i < _shards.Length; i++)
result += _shards[i].PrivateChannels.Count;
return result;
}
}
private IEnumerable<SocketGuild> GetGuilds()
{
@@ -189,7 +195,7 @@ namespace Discord.WebSocket
for (int i = 0; i < _shards.Length; i++)
result += _shards[i].Guilds.Count;
return result;
}
}
/// <inheritdoc />
public override SocketUser GetUser(ulong id)
@@ -369,5 +375,22 @@ namespace Discord.WebSocket
/// <inheritdoc />
Task<IVoiceRegion> IDiscordClient.GetVoiceRegionAsync(string id, RequestOptions options)
=> Task.FromResult<IVoiceRegion>(GetVoiceRegion(id));
internal override void Dispose(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
foreach (var client in _shards)
client?.Dispose();
_connectionGroupLock?.Dispose();
}
_isDisposed = true;
}
base.Dispose(disposing);
}
}
}