问题描述
我们正在做我们想在一个单独的线程中运行的 IO 操作,主线程不应该等待这个操作。
def seperateThread(action: F[Unit]): F[Unit]
ConcurrentEffect[F].start(action).void
for {
_ <- service.seperateThread(request,languageId,cacheItinerary,slices,pricing)
} yield {}
它会在不同的 Fiber 中做 seperateThread
操作并立即返回 F[Unit] 还是等待操作完成?
解决方法
启动纤程是一个非阻塞操作,因此应用程序流将立即转到下一条指令。
为了等待另一个纤程中运行的操作完成,你需要调用纤程对象上的join
操作。您无法在实现中执行此操作,因为您调用了 void
,因此忽略了对 Fiber 的返回引用。
如果你像这样改变你的方法:
def seperateThread[F[_]: ConcurrentEffect: Functor: Sync](action: F[Unit]): F[Fiber[F,Unit]] = ConcurrentEffect[F].start(action)
然后您就可以使用对创建的光纤的引用到 join
:
for {
fiber <- ConcurrentEffect[IO].start(IO(println("Hello from another fiber!")))
// _ <- do some more operations in parallel ...
result <- fiber.join //here you can access value returned by fiber
//(in your case it's Unit so you can just ignore it).
} yield result
在大多数情况下不建议直接使用 Fiber 的 start
,因为这可能导致资源泄漏。您应该考虑使用 background
代替它创建 Resource
,它会在处理结束时自动取消和清理光纤。