Scala 使用“猫赛跑”效果可防止应用程序退出

Scala 使用“猫赛跑”效果可防止应用程序退出,scala,scala-cats,cats-effect,Scala,Scala Cats,Cats Effect,我有一个简单的猫效应应用程序,它从作为参数给出的URL下载站点。在下载过程中,应用程序应该通过向控制台写入点()来显示“加载条”。我通过两个IOs的竞争来实现它,一个用于下载另一个用于显示点 这是整个应用程序 最重要的部分在这里: def loader():IO[Unit]=用于{ _ 为了{ content console.putStrLn(“将url作为参数传递”) } } 一切都按照我的预期运行,当我运行它时,我得到: 。。。。。。。。。。。。。。 从下载的网站。下载内容的大小为477

我有一个简单的猫效应应用程序,它从作为参数给出的URL下载站点。在下载过程中,应用程序应该通过向控制台写入点(
)来显示“加载条”。我通过两个IOs的竞争来实现它,一个用于下载另一个用于显示点

这是整个应用程序

最重要的部分在这里:

def loader():IO[Unit]=用于{
_ 
为了{
content console.putStrLn(“将url作为参数传递”)
}
}
一切都按照我的预期运行,当我运行它时,我得到:

。。。。。。。。。。。。。。 从下载的网站。下载内容的大小为47738

唯一的问题是应用程序永远不会退出

据我所知,加载程序IO被正确取消。我甚至可以添加如下内容:

urlLoader.run(args) *> console.putStrLn("???") *> IO(ExitCode.Success)
并显示

同样,当我删除race时,应用程序将正确退出


因此,我的问题是,如何解决这个问题并在最后退出我的应用程序?

继续我的上述评论:问题是,您的
ScheduledExecutorService
运行的线程阻止JVM退出,即使计时器的任务已取消。有几种方法可以解决此问题:

  • IO(ExitCode.Success)
    之前添加
    IO(ses.shutdown())
  • 使用对其线程进行后台监控的线程工厂调用
    newScheduledThreadPool
  • 使用您在
    IOApp
    中免费获得的
    timer:timer

使用
IOApp
提供的计时器(和
ContextShift
)几乎肯定是正确的选择,这将为您提供合理的默认设置以及其他行为。

您不使用
IOApp
提供的
计时器有什么原因吗?乍一看,问题似乎在于您没有关闭计划程序,如果您使用内置计时器,您就不必担心这一点。我错过了
IOApp
已经profides
计时器
。我从中获取了我的实现。不是,它很有魅力,谢谢!