I have a `Thread` that's already running (for lega...
# coroutines
y
I have a
Thread
that's already running (for legacy reasons, it needs to be a
Thread
for now). Inside a
suspend
function, how can I call
thread.join()
in a "better" manner? As in, so that the coroutine suspends until the thread finishes.
c
Copy code
withContext(<http://Dispatchers.IO|Dispatchers.IO>) { 
    thread.join() 
}
m
There wouldn't be anything built in that is not blocking. Best option would be to add something at the end of the work the thread is doing that would notify listeners when it is done. You can then suspend and wait for the notification. This relies on you having some control over the thread and the work it is doing.
y
Looking at `Thread.join`'s code, it seems to just wait until
thread.isAlive
is false, so wouldn't I be able to use that as a condition to wait for? I do have control over the thread code, but I'm trying to not be too invasive
I came up with this, but I don't know if its better or not:
Copy code
coroutineScope { launch { while (thread.isAlive) delay(10) } }
s
runInterruptible is probably a better choice than
withContext
. A non-blocking option would be to somehow pass a
CompletableDeferred
as the task running in the
Thread
and await that. I would personally prefer
join
in favor of looping, you can potentially also use newSingleThreadContext instead of
<http://Dispatchers.IO|Dispatchers.IO>
but be sure to close it.
c
Oh, indeed
runInterruptible(<http://Dispatchers.IO|Dispatchers.IO>)
looks more appropriate. It's still blocking a thread.
y
Thanks Ivan and Simon. I ended up using a
CompletableDeferred
and completing it at the end of the thread's code, then awaiting it instead of calling
join
c
That's even better 👍
s
That would indeed the best option if possible, be sure to add it in a
try { } finally { }
block so it gets called regardless of exceptions 😉
y
@simon.vergauwen Ooops yes I forgot! Good catch
c
Pun intended? 🤔