Arjan van Wieringen
06/30/2023, 5:57 PMRunnable
which also implements Closable
ino order to clean up which will fully block a thread (I think). I want to run this Runnable in a separate Job and be able to cancel it. I've brought it back to this:
suspend fun main() = coroutineScope {
val engine: Runnable = ....
val job = launch(<http://Dispatchers.IO|Dispatchers.IO>) {
try {
println("Starting engine")
launch { engine.run() }.join() // without join it would go to finally directly of course
} finally {
println("Closing engine")
engine.close()
}
}
delay(1000)
job.cancel()
}
This appears to work, but it looks a bit weird having a seperate Job, only for cancelling.
Just doing this:
val job = launch(<http://Dispatchers.IO|Dispatchers.IO>) { engine.run() }
delay(1000)
job.cancel()
will not work, the engine will keep going.
Also wrapping engine.run()
in 'try / catch' in order to catch the cancellation exception doesn't work because engine.run() fully claims the thread.
Is the above method the correct way?
EDIT:
runInterruptable
seems to be handy here:
val job = launch(<http://Dispatchers.IO|Dispatchers.IO>) {
try {
runInterruptible {
engine.run()
}
} catch (e: CancellationException) {
println("Cancelled")
} finally {
println("Finally")
engine.close()
}
}
ephemient
06/30/2023, 6:04 PMval job = launch(<http://Dispatchers.IO|Dispatchers.IO>) {
runInterruptible {
engine.run()
}
}
job.invokeOnCompletion { engine.close() }
but try
-finally
is clearer IMOArjan van Wieringen
06/30/2023, 6:06 PMArjan van Wieringen
06/30/2023, 6:06 PMArjan van Wieringen
06/30/2023, 6:06 PMsuspend fun <T> T.runAndClose() where T : Runnable, T : Closeable {
try {
runInterruptible { run() }
} finally {
close()
}
}
Which works pretty okayephemient
06/30/2023, 6:07 PMsuspend
calls from the finally
block since they'll immediately fail if the job is cancelled (nor can you from the completion handler, statically). but probably not relevant to you if you're using Closable.close since that's not suspendingArjan van Wieringen
06/30/2023, 6:07 PMArjan van Wieringen
06/30/2023, 6:09 PMval job = launch(<http://Dispatchers.IO|Dispatchers.IO>) {
engine.use {
runInterruptible { it.run() }
}
}