dephinera
02/20/2023, 8:37 AMsuspend fun loadData()withContext(<http://Dispatchers.IO|Dispatchers.IO>)loadData()withContextloadData()Dispatchers.DefaultwithContextdephinera
02/20/2023, 8:37 AMclass MyVM(private val repository: Repository) {
    fun init() {
        viewModelScope.launch(Dispatchers.Main.Immediate) {
            val dataToBeDisplayed = repository.loadData()
            handleResult(dataToBeDisplayed)
        }
    }
}
class Repository {
    suspend fun loadData(): Result {
        return withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
            doIO()
        }
    }
}class MyVM(private val repository: Repository) {
    fun init() {
        viewModelScope.launch(Dispatchers.Main.Immediate) {
            val dataToBeDisplayed = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
                repository.loadData()
            }
            handleResult(dataToBeDisplayed)
        }
    }
}
class Repository {
    suspend fun loadData(): Result {
        return doIO()
    }
}Sam
02/20/2023, 8:40 AMsuspenddephinera
02/20/2023, 8:53 AMSam
02/20/2023, 8:55 AMstojan
02/20/2023, 10:20 AMDispatchers.Main.ImmediatelaunchviewModelScopeDispatchers.Main.Immediategildor
02/21/2023, 2:20 AMSuspend function can call blocking function if wrap it correctly (with appropriate dispatcher and handle cancellation correctly when it’s possilbe), the convention is that suspend function shouldn’t be blocking by itselffunction should not call blocking functionssuspend
Sam
02/21/2023, 7:15 AMRyan Smith
02/22/2023, 1:04 AMSuspend function can call blocking function if wrap it correctly (with appropriate dispatcher and handle cancellation correctly when it’s possilbe)As an example, then, if I wanted to do something like file I/O what would be the correct way to manage it? I have an example here, if it helps:
suspend fun <T> serializeIt(thing: T) {
    withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
        val file = File("out.json")
        file.outputStream().use {
            // Json from kotlinx.serialization
            Json.encodeToStream(thing, it)
        }
    }
}gildor
02/22/2023, 1:51 AMwithContext(…) {
   use {
      coroutineContext.job.invokeOnCompletion { it.close() }
   }
}Ryan Smith
02/22/2023, 1:57 AMinvokeOnCompletiongildor
02/22/2023, 2:00 AMRyan Smith
02/22/2023, 2:05 AMuseCancellationExceptiongildor
02/22/2023, 2:06 AMgildor
02/22/2023, 2:07 AMDoes cancellation not result in aIt would, but your code doesn’t call any suspend function, so cancellation will be thrown when withContext block is finihsed, it will be propagated on topbeing thrownCancellationException
gildor
02/22/2023, 2:15 AMval file = createTempFile()
try {
    file.outputStream().use {
        it.write("{".toByteArray())
        throw CancellationException()
        it.write("}".toByteArray())
    }
} catch (e: CancellationException) {
    println("Resulting file content: ${file.readText()}")
}
println("Completed")gildor
02/22/2023, 2:15 AMResulting file content: {
Completedgildor
02/22/2023, 2:18 AMval file = createTempFile()
try {
    file.outputStream().use {
        it.write("{".toByteArray())
        throw CancellationException()
        it.write("}".toByteArray())
    }
} catch (e: Exception) {
     try {
         file.delete()
     } catch (e: Exception) {
         println("Not able to clean up")
     }
    println("Resulting file exists: ${file.exists()}")
}
println("Completed")
// Out:
// Resulting file exists: false
// Completedgildor
02/22/2023, 2:20 AMRyan Smith
02/22/2023, 2:27 AMuseuseuseuseusegildor
02/22/2023, 2:34 AMgildor
02/22/2023, 2:34 AMRyan Smith
02/22/2023, 2:36 AMgildor
02/22/2023, 2:36 AMRyan Smith
02/22/2023, 2:39 AMgildor
02/22/2023, 2:41 AMRyan Smith
02/22/2023, 2:41 AMgildor
02/22/2023, 2:44 AMRyan Smith
02/22/2023, 2:49 AM