Bukkit/Spigot - 如何等到 BukkitRunnable 完成

Bukkit/Spigot - How to wait until BukkitRunnable is finished

在我的 Main class 中的 onDisbale() 方法中,我有一个循环创建并启动新的 BukkitRunnables。 我在控制台中遇到错误:org.bukkit.plugin.IllegalPluginAccessException: Plugin attempted to register task while disabled
我需要以某种方式在我的 onDisable() 方法中等待,直到我在循环中创建的所有 BukkitRunnables 完成。怎么做?
我的代码如下所示:

@Override
public void onDisable() {
    for (Player p : Bukkit.getOnlinePlayers()) {
        new PlayerDataSaverRunnable().runTaskAsynchronously(this);
    }
}

onDisable 方法是在禁用插件和关闭服务器之前调用的最后一个方法。因此,正如错误消息所说,很遗憾,您无法在 onDisable 函数中安排任何新任务。

您在评论中提到您正在尝试写入插件文件夹中的文件,并且在正常情况下您希望异步执行此操作。但是,因为 onDisable 只会在服务器关闭时被调用(或者当整个服务器重新加载 /reload 时),所以 运行 这里的代码完全没问题,它会阻塞主线程并且可能会占用运行 几秒钟 — 在关闭的情况下,调用此方法时,所有玩家都已经被踢出服务器,因此没有“滞后”可抱怨。如果你的插件是 super 高级并且必须保存一堆东西,我不认为任何服务器所有者会抱怨,即使它需要 10 秒左右的时间来禁用。

当然,您必须保存一些疯狂的东西才能保存整整 10 秒。大多数文件很可能会在几毫秒内保存。

如果您真的不想尽快禁用该插件,您可以考虑执行一些异步任务,每 5 分钟左右执行一次 运行 并自动保存文件。然后,在 onDisable 中,您只能保存自上次自动保存程序以来更改的文件 运行。无论如何,这是一个很好的做法,以防万一服务器崩溃或断电并且 onDisable 方法没有机会 运行。但是,话又说回来,我仍然建议您在 onDisable 方法中保存 everything(这也是我对所有插件所做的),即使它需要几秒钟并阻塞主线程,这样您就可以 100% 确定所有内容都已正确保存。