Home > Net >  How call a function in the background that not block the thread but also wait for return in Kotlin
How call a function in the background that not block the thread but also wait for return in Kotlin

Time:10-14

I have a function that call an internal FFI code that could block the UI:

fun query(q: Request): Response {
    val cmd = Json.encodeToString(q)
    
    // This could take long...
    result = Server.server.query(cmd):

    return try {
        Json.decodeFromString<Response>(result)
    } catch (e: Exception) {
        Response.Fail(UIData.JsonError(kind = "JSON Decode", message = e.toString()))
    }
}

I don't wanna turn all my code async just for this. I wanna call this in a way the UI does not freeze but still wait for the results.

I tried with GlobalScope.launch but it don't return the result, and can't put a channel here because get the result require the function to be suspend.

CodePudding user response:

The function signature fun query(q: Request): Response defines a function that blocks the current thread until Response is available and returned. There is no way around it.

If you don't want to block the current thread, the signature has to change so the function can become asynchronous. One way to do this is to mark the function suspend, which is nice because you don't need to change the design of the code too much, and can keep reasoning sequentially. Another way is to provide a callback to use the result later.

If you decide to mark the function suspend, you're still not done. Server.server.query is likely blocking too, so you would either need to wrap it in a withContext(Dispatchers.IO), or -better- find an async alternative so you can truly be suspending.

CodePudding user response:

If you can change the signature of the function to return a Deferred<Response>, you can wrap your blocking query in a GlobalScope.async(Dispatchers.IO) {}

  • Related