diff --git a/DSharpPlus.CommandsNext/CommandsNextExtension.cs b/DSharpPlus.CommandsNext/CommandsNextExtension.cs
index fc52c0775a..06bf12fea8 100644
--- a/DSharpPlus.CommandsNext/CommandsNextExtension.cs
+++ b/DSharpPlus.CommandsNext/CommandsNextExtension.cs
@@ -166,11 +166,11 @@ internal CommandsNextExtension(CommandsNextConfiguration cfg)
/// Disposes of this the resources used by CNext.
///
public override void Dispose()
- => this.Config.CommandExecutor.Dispose();
-
- ~CommandsNextExtension()
{
- this.Dispose();
+ this.Config.CommandExecutor.Dispose();
+
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
#region DiscordClient Registration
diff --git a/DSharpPlus.Interactivity/EventHandling/EventWaiter.cs b/DSharpPlus.Interactivity/EventHandling/EventWaiter.cs
index 2fd04f61d9..606f957977 100644
--- a/DSharpPlus.Interactivity/EventHandling/EventWaiter.cs
+++ b/DSharpPlus.Interactivity/EventHandling/EventWaiter.cs
@@ -133,31 +133,33 @@ private Task HandleEvent(DiscordClient client, T eventargs)
return Task.CompletedTask;
}
- ~EventWaiter()
- {
- this.Dispose();
- }
-
///
/// Disposes this EventWaiter
///
public void Dispose()
{
+ if (this._disposed)
+ return;
+
this._disposed = true;
- if (this._event != null)
+
+ if (this._event != null && this._handler != null)
this._event.Unregister(this._handler);
- this._event = null;
- this._handler = null;
- this._client = null;
+ this._event = null!;
+ this._handler = null!;
+ this._client = null!;
if (this._matchrequests != null)
this._matchrequests.Clear();
if (this._collectrequests != null)
this._collectrequests.Clear();
- this._matchrequests = null;
- this._collectrequests = null;
+ this._matchrequests = null!;
+ this._collectrequests = null!;
+
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/DSharpPlus.Interactivity/EventHandling/Paginator.cs b/DSharpPlus.Interactivity/EventHandling/Paginator.cs
index 65c7f0d018..9d9d27548b 100644
--- a/DSharpPlus.Interactivity/EventHandling/Paginator.cs
+++ b/DSharpPlus.Interactivity/EventHandling/Paginator.cs
@@ -260,22 +260,23 @@ private async Task PaginateAsync(IPaginationRequest p, DiscordEmoji emoji)
await builder.ModifyAsync(msg).ConfigureAwait(false);
}
- ~Paginator()
- {
- this.Dispose();
- }
-
///
/// Disposes this EventWaiter
///
public void Dispose()
{
- this._client.MessageReactionAdded -= this.HandleReactionAdd;
- this._client.MessageReactionRemoved -= this.HandleReactionRemove;
- this._client.MessageReactionsCleared -= this.HandleReactionClear;
- this._client = null;
- this._requests.Clear();
- this._requests = null;
+ // Why doesn't this class implement IDisposable?
+
+ if (this._client != null)
+ {
+ this._client.MessageReactionAdded -= this.HandleReactionAdd;
+ this._client.MessageReactionRemoved -= this.HandleReactionRemove;
+ this._client.MessageReactionsCleared -= this.HandleReactionClear;
+ this._client = null!;
+ }
+
+ this._requests?.Clear();
+ this._requests = null!;
}
}
}
diff --git a/DSharpPlus.Interactivity/EventHandling/Poller.cs b/DSharpPlus.Interactivity/EventHandling/Poller.cs
index af86b2300e..0caa81a4c7 100644
--- a/DSharpPlus.Interactivity/EventHandling/Poller.cs
+++ b/DSharpPlus.Interactivity/EventHandling/Poller.cs
@@ -128,22 +128,26 @@ private Task HandleReactionClear(DiscordClient client, MessageReactionsClearEven
return Task.CompletedTask;
}
- ~Poller()
- {
- this.Dispose();
- }
-
///
/// Disposes this EventWaiter
///
public void Dispose()
{
- this._client.MessageReactionAdded -= this.HandleReactionAdd;
- this._client.MessageReactionRemoved -= this.HandleReactionRemove;
- this._client.MessageReactionsCleared -= this.HandleReactionClear;
- this._client = null;
- this._requests.Clear();
- this._requests = null;
+ // Why doesn't this class implement IDisposable?
+
+ if (this._client != null)
+ {
+ this._client.MessageReactionAdded -= this.HandleReactionAdd;
+ this._client.MessageReactionRemoved -= this.HandleReactionRemove;
+ this._client.MessageReactionsCleared -= this.HandleReactionClear;
+ this._client = null!;
+ }
+
+ if (this._requests != null)
+ {
+ this._requests.Clear();
+ this._requests = null!;
+ }
}
}
}
diff --git a/DSharpPlus.Interactivity/EventHandling/ReactionCollector.cs b/DSharpPlus.Interactivity/EventHandling/ReactionCollector.cs
index b229d238e3..b7938549e9 100644
--- a/DSharpPlus.Interactivity/EventHandling/ReactionCollector.cs
+++ b/DSharpPlus.Interactivity/EventHandling/ReactionCollector.cs
@@ -168,31 +168,34 @@ private Task HandleReactionClear(DiscordClient client, MessageReactionsClearEven
return Task.CompletedTask;
}
- ~ReactionCollector()
- {
- this.Dispose();
- }
-
///
/// Disposes this EventWaiter
///
public void Dispose()
{
- this._client = null;
+ this._client = null!;
+
+ if (this._reactionAddHandler != null)
+ this._reactionAddEvent?.Unregister(this._reactionAddHandler);
- this._reactionAddEvent.Unregister(this._reactionAddHandler);
- this._reactionRemoveEvent.Unregister(this._reactionRemoveHandler);
- this._reactionClearEvent.Unregister(this._reactionClearHandler);
+ if (this._reactionRemoveHandler != null)
+ this._reactionRemoveEvent?.Unregister(this._reactionRemoveHandler);
- this._reactionAddEvent = null;
- this._reactionAddHandler = null;
- this._reactionRemoveEvent = null;
- this._reactionRemoveHandler = null;
- this._reactionClearEvent = null;
- this._reactionClearHandler = null;
+ if (this._reactionClearHandler != null)
+ this._reactionClearEvent?.Unregister(this._reactionClearHandler);
- this._requests.Clear();
- this._requests = null;
+ this._reactionAddEvent = null!;
+ this._reactionAddHandler = null!;
+ this._reactionRemoveEvent = null!;
+ this._reactionRemoveHandler = null!;
+ this._reactionClearEvent = null!;
+ this._reactionClearHandler = null!;
+
+ this._requests?.Clear();
+ this._requests = null!;
+
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
}
@@ -214,19 +217,16 @@ public ReactionCollectRequest(DiscordMessage msg, TimeSpan timeout)
this._ct.Token.Register(() => this._tcs.TrySetResult(null));
}
- ~ReactionCollectRequest()
- {
- this.Dispose();
- }
-
public void Dispose()
{
- GC.SuppressFinalize(this);
this._ct.Dispose();
this._tcs = null;
this._message = null;
this._collected?.Clear();
this._collected = null;
+
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
}
diff --git a/DSharpPlus.Interactivity/EventHandling/Requests/CollectRequest.cs b/DSharpPlus.Interactivity/EventHandling/Requests/CollectRequest.cs
index 013fd1836e..2e25649904 100644
--- a/DSharpPlus.Interactivity/EventHandling/Requests/CollectRequest.cs
+++ b/DSharpPlus.Interactivity/EventHandling/Requests/CollectRequest.cs
@@ -57,24 +57,19 @@ public CollectRequest(Func predicate, TimeSpan timeout)
this._collected = new ConcurrentHashSet();
}
- ~CollectRequest()
- {
- this.Dispose();
- }
-
///
/// Disposes this CollectRequest.
///
public void Dispose()
{
this._ct.Dispose();
- this._tcs = null;
- this._predicate = null;
+ this._tcs = null!;
+ this._predicate = null!;
if (this._collected != null)
{
this._collected.Clear();
- this._collected = null;
+ this._collected = null!;
}
}
}
diff --git a/DSharpPlus.Interactivity/EventHandling/Requests/MatchRequest.cs b/DSharpPlus.Interactivity/EventHandling/Requests/MatchRequest.cs
index 08a812a95f..f1d6387910 100644
--- a/DSharpPlus.Interactivity/EventHandling/Requests/MatchRequest.cs
+++ b/DSharpPlus.Interactivity/EventHandling/Requests/MatchRequest.cs
@@ -54,19 +54,17 @@ public MatchRequest(Func predicate, TimeSpan timeout)
this._timeout = timeout;
}
- ~MatchRequest()
- {
- this.Dispose();
- }
-
///
/// Disposes this MatchRequest.
///
public void Dispose()
{
- this._ct.Dispose();
- this._tcs = null;
- this._predicate = null;
+ this._ct?.Dispose();
+ this._tcs = null!;
+ this._predicate = null!;
+
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/DSharpPlus.Interactivity/EventHandling/Requests/PaginationRequest.cs b/DSharpPlus.Interactivity/EventHandling/Requests/PaginationRequest.cs
index e293819026..2033a04079 100644
--- a/DSharpPlus.Interactivity/EventHandling/Requests/PaginationRequest.cs
+++ b/DSharpPlus.Interactivity/EventHandling/Requests/PaginationRequest.cs
@@ -195,18 +195,15 @@ public async Task> GetTaskCompletionSourceAsync()
return this._tcs;
}
- ~PaginationRequest()
- {
- this.Dispose();
- }
-
///
/// Disposes this PaginationRequest.
///
public void Dispose()
{
- this._ct.Dispose();
- this._tcs = null;
+ // Why doesn't this class implement IDisposable?
+
+ this._ct?.Dispose();
+ this._tcs = null!;
}
}
}
diff --git a/DSharpPlus.Interactivity/EventHandling/Requests/PollRequest.cs b/DSharpPlus.Interactivity/EventHandling/Requests/PollRequest.cs
index 3b8b195eaa..3c1959d61e 100644
--- a/DSharpPlus.Interactivity/EventHandling/Requests/PollRequest.cs
+++ b/DSharpPlus.Interactivity/EventHandling/Requests/PollRequest.cs
@@ -99,18 +99,15 @@ internal void AddReaction(DiscordEmoji emoji, DiscordUser member)
}
}
- ~PollRequest()
- {
- this.Dispose();
- }
-
///
/// Disposes this PollRequest.
///
public void Dispose()
{
- this._ct.Dispose();
- this._tcs = null;
+ // Why doesn't this class implement IDisposable?
+
+ this._ct?.Dispose();
+ this._tcs = null!;
}
}
diff --git a/DSharpPlus.Interactivity/InteractivityExtension.cs b/DSharpPlus.Interactivity/InteractivityExtension.cs
index c458667c7e..906eb109ac 100644
--- a/DSharpPlus.Interactivity/InteractivityExtension.cs
+++ b/DSharpPlus.Interactivity/InteractivityExtension.cs
@@ -1060,21 +1060,19 @@ private async Task HandleInvalidInteraction(DiscordInteraction interaction)
public override void Dispose()
{
- this.ComponentEventWaiter.Dispose();
- this.ModalEventWaiter.Dispose();
- this.ReactionCollector.Dispose();
- this.ComponentInteractionWaiter.Dispose();
- this.MessageCreatedWaiter.Dispose();
- this.MessageReactionAddWaiter.Dispose();
- this.Paginator.Dispose();
- this.Poller.Dispose();
- this.TypingStartWaiter.Dispose();
- this._compPaginator.Dispose();
- }
-
- ~InteractivityExtension()
- {
- this.Dispose();
+ this.ComponentEventWaiter?.Dispose();
+ this.ModalEventWaiter?.Dispose();
+ this.ReactionCollector?.Dispose();
+ this.ComponentInteractionWaiter?.Dispose();
+ this.MessageCreatedWaiter?.Dispose();
+ this.MessageReactionAddWaiter?.Dispose();
+ this.Paginator?.Dispose();
+ this.Poller?.Dispose();
+ this.TypingStartWaiter?.Dispose();
+ this._compPaginator?.Dispose();
+
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/DSharpPlus.Lavalink/LavalinkExtension.cs b/DSharpPlus.Lavalink/LavalinkExtension.cs
index 7e16fe51b0..daefcfe752 100644
--- a/DSharpPlus.Lavalink/LavalinkExtension.cs
+++ b/DSharpPlus.Lavalink/LavalinkExtension.cs
@@ -199,22 +199,19 @@ private Task Con_Disconnected(LavalinkNodeConnection node, NodeDisconnectedEvent
public override void Dispose()
{
- foreach(var node in this._connectedNodes)
+ foreach (var node in this._connectedNodes)
{
// undoubtedly there will be some GitHub comments about this. Help.
node.Value.StopAsync().GetAwaiter().GetResult();
}
- this._connectedNodes.Clear();
- // unhook events
- _nodeDisconnected.UnregisterAll();
+ this._connectedNodes?.Clear();
- // Hi GC! <3 😘 clean me up uwu
- }
+ // unhook events
+ this._nodeDisconnected?.UnregisterAll();
- ~LavalinkExtension()
- {
- this.Dispose();
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/DSharpPlus.Rest/DiscordRestClient.cs b/DSharpPlus.Rest/DiscordRestClient.cs
index d4c569c33d..e48e9bf1fc 100644
--- a/DSharpPlus.Rest/DiscordRestClient.cs
+++ b/DSharpPlus.Rest/DiscordRestClient.cs
@@ -2293,7 +2293,7 @@ public override void Dispose()
return;
this._disposed = true;
this._guilds = null;
- this.ApiClient._rest.Dispose();
+ this.ApiClient?._rest?.Dispose();
}
}
}
diff --git a/DSharpPlus.SlashCommands/SlashCommandsExtension.cs b/DSharpPlus.SlashCommands/SlashCommandsExtension.cs
index 5ffec91ddb..93e81035fd 100644
--- a/DSharpPlus.SlashCommands/SlashCommandsExtension.cs
+++ b/DSharpPlus.SlashCommands/SlashCommandsExtension.cs
@@ -1238,23 +1238,24 @@ public event AsyncEventHandler
/// Connects to the specified voice channel.
///
@@ -724,15 +719,15 @@ public void Dispose()
this.IsDisposed = true;
this.IsInitialized = false;
- this.TokenSource.Cancel();
- this.SenderTokenSource.Cancel();
+ this.TokenSource?.Cancel();
+ this.SenderTokenSource?.Cancel();
this.ReceiverTokenSource?.Cancel();
- this.KeepaliveTokenSource.Cancel();
+ this.KeepaliveTokenSource?.Cancel();
- this.TokenSource.Dispose();
- this.SenderTokenSource.Dispose();
+ this.TokenSource?.Dispose();
+ this.SenderTokenSource?.Dispose();
this.ReceiverTokenSource?.Dispose();
- this.KeepaliveTokenSource.Dispose();
+ this.KeepaliveTokenSource?.Dispose();
try
{
@@ -742,11 +737,11 @@ public void Dispose()
catch { }
this.Opus?.Dispose();
- this.Opus = null;
+ this.Opus = null!;
this.Sodium?.Dispose();
- this.Sodium = null;
+ this.Sodium = null!;
this.Rtp?.Dispose();
- this.Rtp = null;
+ this.Rtp = null!;
this.VoiceDisconnected?.Invoke(this.Guild);
}
diff --git a/DSharpPlus.VoiceNext/VoiceNextExtension.cs b/DSharpPlus.VoiceNext/VoiceNextExtension.cs
index b96d7e7ca9..cdb1a014fd 100644
--- a/DSharpPlus.VoiceNext/VoiceNextExtension.cs
+++ b/DSharpPlus.VoiceNext/VoiceNextExtension.cs
@@ -229,18 +229,20 @@ private async Task Client_VoiceServerUpdate(DiscordClient client, VoiceServerUpd
public override void Dispose()
{
- foreach(var conn in this.ActiveConnections)
+ foreach (var conn in this.ActiveConnections)
{
- conn.Value.Dispose();
+ conn.Value?.Dispose();
+ }
+
+ if (this.Client != null)
+ {
+ this.Client.VoiceStateUpdated -= this.Client_VoiceStateUpdate;
+ this.Client.VoiceServerUpdated -= this.Client_VoiceServerUpdate;
}
- this.Client.VoiceStateUpdated -= this.Client_VoiceStateUpdate;
- this.Client.VoiceServerUpdated -= this.Client_VoiceServerUpdate;
// Lo and behold, the audacious man who dared lay his hand upon VoiceNext hath once more trespassed upon its profane ground!
- }
- ~VoiceNextExtension()
- {
- this.Dispose();
+ // Satisfy rule CA1816. Can be removed if this class is sealed.
+ GC.SuppressFinalize(this);
}
}
}
diff --git a/DSharpPlus.targets b/DSharpPlus.targets
index 9315078d9e..deaf2977ca 100644
--- a/DSharpPlus.targets
+++ b/DSharpPlus.targets
@@ -1,7 +1,7 @@
- 4.4.1
+ 4.4.2
1591
9.0
True
diff --git a/DSharpPlus/Clients/DiscordClient.cs b/DSharpPlus/Clients/DiscordClient.cs
index 180bd93b03..38ff52f0ba 100644
--- a/DSharpPlus/Clients/DiscordClient.cs
+++ b/DSharpPlus/Clients/DiscordClient.cs
@@ -1030,13 +1030,8 @@ private void PopulateMessageReactionsAndCache(DiscordMessage message, TransportU
#region Disposal
- ~DiscordClient()
- {
- this.Dispose();
- }
-
-
private bool _disposed;
+
///
/// Disposes your DiscordClient.
///
@@ -1046,17 +1041,19 @@ public override void Dispose()
return;
this._disposed = true;
- GC.SuppressFinalize(this);
- this.DisconnectAsync().ConfigureAwait(false).GetAwaiter().GetResult();
- this.ApiClient._rest.Dispose();
- this.CurrentUser = null;
+ this.DisconnectAsync().GetAwaiter().GetResult();
+ this.ApiClient?._rest?.Dispose();
+ this.CurrentUser = null!;
var extensions = this._extensions; // prevent _extensions being modified during dispose
- this._extensions = null;
+ this._extensions = null!;
+
foreach (var extension in extensions)
+ {
if (extension is IDisposable disposable)
disposable.Dispose();
+ }
try
{
@@ -1065,9 +1062,9 @@ public override void Dispose()
}
catch { }
- this._guilds = null;
- this._heartbeatTask = null;
- this._privateChannels = null;
+ this._guilds = null!;
+ this._heartbeatTask = null!;
+ this._privateChannels = null!;
}
#endregion
diff --git a/DSharpPlus/Clients/DiscordShardedClient.cs b/DSharpPlus/Clients/DiscordShardedClient.cs
index 25d80fa124..2545110e99 100644
--- a/DSharpPlus/Clients/DiscordShardedClient.cs
+++ b/DSharpPlus/Clients/DiscordShardedClient.cs
@@ -402,12 +402,12 @@ private Task InternalStopAsync(bool enableLogger = true)
if (!this._isStarted)
throw new InvalidOperationException("This client has not been started.");
+ this._isStarted = false;
+
if (enableLogger)
this.Logger.LogInformation(LoggerEvents.ShardShutdown, "Disposing {ShardCount} shards.", this._shards.Count);
- this._isStarted = false;
this._voiceRegionsLazy = null;
-
this.GatewayInfo = null;
this.CurrentUser = null;
this.CurrentApplication = null;
@@ -671,7 +671,10 @@ private int GetShardIdFromGuilds(ulong id)
#region Destructor
~DiscordShardedClient()
- => this.InternalStopAsync(false).GetAwaiter().GetResult();
+ {
+ if (this._isStarted)
+ this.InternalStopAsync(false).GetAwaiter().GetResult();
+ }
#endregion
}
diff --git a/DSharpPlus/Clients/DiscordWebhookClient.cs b/DSharpPlus/Clients/DiscordWebhookClient.cs
index 869404f098..6e6823aa51 100644
--- a/DSharpPlus/Clients/DiscordWebhookClient.cs
+++ b/DSharpPlus/Clients/DiscordWebhookClient.cs
@@ -272,8 +272,8 @@ public async Task> BroadcastMessageAs
~DiscordWebhookClient()
{
- this._hooks.Clear();
- this._hooks = null;
+ this._hooks?.Clear();
+ this._hooks = null!;
this._apiclient._rest.Dispose();
}
}
diff --git a/DSharpPlus/Net/Rest/RestClient.cs b/DSharpPlus/Net/Rest/RestClient.cs
index abed35bb40..155de7f5ed 100644
--- a/DSharpPlus/Net/Rest/RestClient.cs
+++ b/DSharpPlus/Net/Rest/RestClient.cs
@@ -677,9 +677,6 @@ private async Task CleanupBucketsAsync()
this.Logger.LogDebug(LoggerEvents.RestCleaner, "Bucket cleaner task stopped.");
}
- ~RestClient()
- => this.Dispose();
-
public void Dispose()
{
if (this._disposed)
@@ -687,7 +684,7 @@ public void Dispose()
this._disposed = true;
- this.GlobalRateLimitEvent.Reset();
+ this.GlobalRateLimitEvent?.Reset();
if (this._bucketCleanerTokenSource?.IsCancellationRequested == false)
{
@@ -703,9 +700,9 @@ public void Dispose()
}
catch { }
- this.RoutesToHashes.Clear();
- this.HashesToBuckets.Clear();
- this.RequestQueue.Clear();
+ this.RoutesToHashes?.Clear();
+ this.HashesToBuckets?.Clear();
+ this.RequestQueue?.Clear();
}
}
}