0

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;
    }
}
nop
  • 4,711
  • 6
  • 32
  • 93
  • What is wrong with the answer you posted ? which part don't you understand ? Because you will be lucky if this doesn't get marked as exactly that duplicate – TheGeneral Feb 26 '21 at 08:17
  • @00110001, in this case, since the HostedService is singleton as well as DiscordSocketClient and CommandService, I don't have to, correct? – nop Feb 26 '21 at 08:21
  • 1
    There is nothing wrong unsubscribing (and its good practice), think of the situation where you refactor, or change the scope (or some developer does), in this situation its not needed (as you have eluded to) as its scope is the life time of the application and the subscriptions cleaned up anyway. so you are correct – TheGeneral Feb 26 '21 at 08:23
  • @00110001, thank you, that's what I wanted to know! – nop Feb 26 '21 at 08:24

0 Answers0