gradle 关闭应用程序后未终止的线程

sh7euo9m  于 2023-08-06  发布在  其他
关注(0)|答案(2)|浏览(162)

我试图使用Discord4J API创建一个discord bot,但是当我尝试从IntelliJ或CMD运行应用程序时,当我退出应用程序时,bot仍然处于活动状态,在我的任务管理器中,我可以看到此应用程序创建的活动线程,唯一的方法是手动结束任务管理器中的任务。
我遵循了官方Discord4J wiki Music-Bot-Tutorial提供的步骤,它提到了If you wish to disconnect your bot, click on the Exit button in the console.,但这并没有发生在我的程序中。
这是我使用的代码:

public static void main(String[] args) throws Exception {
  DiscordClient client = DiscordClientBuilder.create(BOT_TOKEN).build();
  GatewayDiscordClient gateway = client.login().block();

  gateway.onDisconnect().block();
}

字符串
Gradle仅在我尝试停止应用程序Execution failed for task ':SampleBot.main()'. Build cancelled while executing task ':SampleBot.main()'时提供此详细信息

gzszwxb4

gzszwxb41#

通过单击“停止”按钮,您将强制关闭应用程序,而不会让它正确终止。如果机器人仍然在线,那是因为由于这种强制关闭,它永远不会向Discord发送“断开连接”消息。您看到的线程来自gradle,默认情况下它作为守护进程运行,这意味着它始终处于活动状态,以便在下次使用时更快地启动应用程序。
如果你想正确地关闭你的机器人,你应该在你的代码中添加一些逻辑,通过示例监听控制台中的输入并调用client.logout().block();

c2e8gylq

c2e8gylq2#

看起来这个问题可能与您如何处理Discord bot应用程序的终止有关。当您使用您提供的代码运行bot时,它会使用gateway.onDisconnect().block();阻塞主线程,从而阻止应用程序在您尝试退出时正确终止。
要在您想要退出应用程序时优雅地关闭Discord bot,您可以使用CountDownLatch。下面是如何修改代码来实现这一点:

```java
import reactor.core.publisher.Mono;
import java.util.concurrent.CountDownLatch;

public class SampleBot {
    private static final String BOT_TOKEN = "your_bot_token_here";

    public static void main(String[] args) throws Exception {
        DiscordClient client = DiscordClientBuilder.create(BOT_TOKEN).build();
        GatewayDiscordClient gateway = client.login().block();

        // Initialize the latch with 1 permit
        CountDownLatch latch = new CountDownLatch(1);

        // Add a shutdown hook to gracefully disconnect the bot when the application is terminated
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("Shutting down bot...");
            gateway.logout().block();
            latch.countDown();
        }));

        // Wait until the latch reaches 0 (i.e., the bot is disconnected)
        latch.await();
    }
}
字符串
通过这种修改,当您运行bot时,它将启动并使用`latch.await()`阻塞主线程。但是,当您退出应用程序时(例如,通过单击控制台中的Exit按钮),将触发shutdown钩子,注销bot并释放闩锁,允许主线程继续运行,应用程序正常终止。
通过使用这种方法,在退出应用程序后,您将不会再在任务管理器中看到活动线程,因为bot将在应用程序终止前正确断开连接。

相关问题