I wonder if we should unsubscribe the events we subscribed to, because the examples in their documentation don't, but there are other examples that I found and they do. Please elaborate why.
Should I unsubscribe from events?
Basically, if you are sure that the subscribing object is going to outlive the event source, you ought to unsubscribe, otherwise this would create an unnecessary reference.
services.AddSingleton(new DiscordSocketClient(new DiscordSocketConfig { LogLevel = LogSeverity.Info }));
services.AddSingleton(new CommandService(new CommandServiceConfig { LogLevel = LogSeverity.Info }));
services.AddHostedService<DiscordHostedService>();
public class DiscordHostedService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private readonly IServiceProvider _serviceProvider;
private readonly IOptions<DiscordOptions> _discordOptions;
private readonly DiscordSocketClient _client;
private readonly CommandService _commands;
public DiscordHostedService(
ILogger logger,
IServiceProvider serviceProvider,
IOptions<DiscordOptions> discordOptions,
DiscordSocketClient client,
CommandService commands)
{
_logger = logger;
_serviceProvider = serviceProvider;
_discordOptions = discordOptions;
_client = client;
_commands = commands;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_client.Ready += ReadyAsync;
_client.MessageReceived += HandleCommandAsync;
_client.Log += LogAsync;
_commands.CommandExecuted += CommandExecutedAsync;
_commands.Log += LogAsync;
await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _serviceProvider);
await _client.LoginAsync(TokenType.Bot, _discordOptions.Value.Token);
await _client.StartAsync();
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await _client.SetStatusAsync(UserStatus.Offline);
await _client.SetGameAsync(null);
await _client.StopAsync();
_client.Ready -= ReadyAsync;
_client.MessageReceived -= HandleCommandAsync;
_client.Log -= LogAsync;
_commands.CommandExecuted -= CommandExecutedAsync;
_commands.Log -= LogAsync;
}
private async Task ReadyAsync()
{
...
}
private async Task HandleCommandAsync(SocketMessage messageParam)
{
...
}
private Task LogAsync(LogMessage messageParam)
{
return Task.CompletedTask;
}
public async Task CommandExecutedAsync(Optional<CommandInfo> command, ICommandContext context, IResult result)
{
...
}
private bool _disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
if (_client != null)
{
_client.Dispose();
}
}
_disposed = true;
}
}