https://kotlinlang.org logo
#coroutines
Title
# coroutines
n

Niklas Gürtler

01/29/2021, 10:59 AM
Another possibility might be
Copy code
val coroJob = AtomicReference<Job> ()
    /// Start my coroutine, may be called from any thread
    fun startCoro () {

        val coro = coroutineScope.launch(<http://Dispatchers.IO|Dispatchers.IO>, start = LAZY) {
            // Do the actual work here ...
            coroJob.set(null)
        }

        // If coroJob isn't null, do nothing.
        if (coroJob.compareAndSet(null, coro))
            coro.start()
    }
which avoids the explicit context switches and should still be thread-safe. Is there a more idiomatic and safe way to do that?
u

uli

01/29/2021, 11:07 PM
What happens if you make coro a property and just start it multiple times?
n

Niklas Gürtler

01/29/2021, 11:28 PM
Dunno, probably an exception 😉
u

uli

01/29/2021, 11:32 PM
Dunno? But are you interested in finding out? You could check the kdoc. It might solve your problem?
n

Niklas Gürtler

02/01/2021, 7:56 AM
Ah, it will simply return false and not do anything if that coro was already started or completed. So not very useful here.
u

uli

02/01/2021, 8:00 AM
Isn't that what you want? Star a coro the first time startCoro is called and do nothing if it is already started?
n

Niklas Gürtler

02/01/2021, 8:00 AM
but i want to re-start it if it was completed
u

uli

02/01/2021, 9:50 AM
I see. Then I guess it does not get much simpler then what you have.
Just watch out for a coroutine leak. In the code above, you are always launching a new coroutine, leaving it dangling in the
NEW
state.
n

Niklas Gürtler

02/01/2021, 9:56 AM
It's not launched, just created (lazy)... Doesn't it get GC'd?
u

uli

02/01/2021, 9:56 AM
No. It is launched lazy
n

Niklas Gürtler

02/01/2021, 9:57 AM
But there isn't any reference to the Job, so it can't ever be launched, so the GC should collect it?
u

uli

02/01/2021, 9:57 AM
I would expect it to stay around
if you start it, there still is no ref and it would live until completed
n

Niklas Gürtler

02/01/2021, 9:57 AM
maybe an
else coro.cancel()
would help
u

uli

02/01/2021, 10:06 AM
How about this one?
Copy code
val coroRunning = AtomicBoolean(false)

/// Start my coroutine, may be called from any thread
fun startCoro () {
    // If coro is running, do nothing.
    if (coroRunning.compareAndExchange(false, true)) {
        coroutineScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
            // Do the actual work here ...
            coroRunning.set(false)
        }
    }
}
n

Niklas Gürtler

02/01/2021, 10:07 AM
looks nice... Hmm, I think some requirements changed and I have to do the whole thing differently 🤦‍♂️ thanks anyways 😄
u

uli

02/01/2021, 10:08 AM
🙂 - Good luck
3 Views