java.lang.IllegalStateException:任务已安排或已取消

时间:2018-04-18 19:42:26

标签: java

当我启动TimerTask然后我完成,然后再次启动它显示此错误,为什么? 这个错误:

[16:30:02] [Client thread/INFO] [MacroSK]: KEY_L
[16:30:06] [Client thread/INFO] [MacroSK]: KEY_O
[16:30:08] [Client thread/INFO] [MacroSK]: KEY_L
[16:30:08] [Client thread/ERROR] [FML]: Exception caught during firing event net.minecraftforge.fml.common.gameevent.TickEvent$ClientTickEvent@1bc14017:
java.lang.IllegalStateException: Task already scheduled or cancelled
    at java.util.Timer.sched(Unknown Source) ~[?:1.8.0_161]
    at java.util.Timer.scheduleAtFixedRate(Unknown Source) ~[?:1.8.0_161]
    at com.skelletonx.MacroSK.handler.KeybindHandler.Shopmsg(KeybindHandler.java:53) ~[KeybindHandler.class:?]
    at com.skelletonx.MacroSK.handler.KeybindHandler.onTickEvent(KeybindHandler.java:63) ~[KeybindHandler.class:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_6_KeybindHandler_onTickEvent_ClientTickEvent.invoke(.dynamic) ~[?:?]
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:55) ~[ASMEventHandler.class:?]
    at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:140) [EventBus.class:?]
    at net.minecraftforge.fml.common.FMLCommonHandler.onPostClientTick(FMLCommonHandler.java:371) [FMLCommonHandler.class:?]
    at net.minecraft.client.Minecraft.func_71407_l(Minecraft.java:2152) [bsu.class:?]
    at net.minecraft.client.Minecraft.func_71411_J(Minecraft.java:1028) [bsu.class:?]
    at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:345) [bsu.class:?]
    at net.minecraft.client.main.Main.main(SourceFile:120) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_161]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_161]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_161]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]

我的代码:

Timer timer = new Timer();
final TimerTask ts = new TimerTask(){
      @Override
      public void run() {
          Minecraft.getMinecraft().thePlayer.sendChatMessage(Ini.getIni("Loja"));
      }
    };
int delaymsg = Integer.parseInt(Ini.getIni("DelayL"));
public void Shopmsg() {
    timer.scheduleAtFixedRate(ts,1000*delaymsg,1000*delaymsg);
}

@SideOnly(Side.CLIENT)
@SubscribeEvent(priority=EventPriority.NORMAL, receiveCanceled=true)
public void onTickEvent(TickEvent.ClientTickEvent event) {
    if(event.phase == TickEvent.Phase.END) {
        if (mc.inGameHasFocus) {
            if (keyBindings[0].isPressed()) {
                LogHelper.info("KEY_L");
                Shopmsg();
            }
            if(keyBindings[1].isPressed()) {
                LogHelper.info("KEY_O");
                 ts.cancel();

            }
        }
    }
} 

当我完成TaskTime时,我怎么能这样做,我可以重新开始? 如果没有停止,停止并重新启动任务时间是否可以暂停和恢复?

2 个答案:

答案 0 :(得分:6)

TimerTask只能由Timer一次安排。

继续使用Timer,您需要每次TimerTask ts重新创建新的ShopMsg()

尽管Timer已被ScheduledExecutorService取代,但值得一提。这通常更灵活......

E.g。创建执行程序(代替Timer):

    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

然后安排循环:

    ScheduledFuture<?> future = scheduledExecutorService.scheduleAtFixedRate(
            () -> Minecraft.getMinecraft().thePlayer.sendChatMessage(Ini.getIni("Loja")),
            delaymsg, 
            delaymsg, 
            TimeUnit.SECONDS);

要停止这个时间表:

    future.cancel(false);

答案 1 :(得分:0)

这种类似闭包的方法怎么样: (高级代码,但仍然很可爱且可行)`

...
<inside method>
...
class NewTimerTask extends TimerTask {
            @Override
            public void run() {
                actionToBePerformed.run();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        NewTimerTask.this.run();
                    }
                }, countOffset(morningHour, eveningHour));
            }
        }

        timer.schedule(new NewTimerTask(), countOffset(morningHour, eveningHour));