How can I detect when I'm done creating directories recursively with Kotlin Coroutines?

dd330825197610124545 注册会员
6 days ago

I didn't test this. Just an idea. Wrap your parallel work in coroutineScope so the suspend function won't return until all the inner jobs are finished.

Also, your suspend function is improper because it is marked suspend but calls blocking functions without wrapping them in withContext. This forces you to wrap calls to this function with an IO dispatcher, which defeats the purpose of marking it suspend and also breaks the convention for suspend functions.

But I could be wrong. Maybe getOrCreateDirectory() is a properly composed suspend function that internally delegates to an appropriate dispatcher. But if that's the case, you shouldn't have to specify the IO dispatcher when you launch coroutines that call this function. A proper suspend function can always be safely called from any dispatcher, because it's supposed to actually suspend and not block.

In the code below I'm assuming getOrCreateDirectory is a suspend function that wraps its blocking work in withContext(Dispatchers.IO).

private suspend fun createDirectoryStructure(directoryBeingBuiltId: String, directoryBeingBuiltUri: Uri) {
    coroutineScope {
        // Create subdirectories for all children of directoryBeingBuilt.
        directoryMap[directoryBeingBuiltId]?.forEach { childDirectory ->
            // Create a directory for each childDirectory and set its Uri in directoryMap.
            val currentSubdirectoryUri = getOrCreateDirectory(directoryBeingBuiltUri, childDirectory.directoryName)!!
            childDirectory.directoryUri = currentSubdirectoryUri
            // Set the subdirectory we just built as directoryBeingBuilt and re-run this recursively.
            launch {
                createDirectoryStructure(childDirectory.directoryId, currentSubdirectoryUri)

So now if you call this function in a suspend function (without needing to wrap it in withContext!), it will suspend until all those directories are created or an IOException is thrown.