0

What I want to do is to translate a list of texts with google cloud translation which is works but sometimes it is very slow. So after 10 seconds I want to cancel it and with withTimeoutOrNull block but it doesn't cancel the operation it keeps running even after the timeout.

  lifecycleScope.launch {
                withContext(Dispatchers.IO) {   
     var imageClassesListInHungarian = listOf<String>()
                        withTimeoutOrNull(10000) {
                            imageClassesListInHungarian = translateList(
                                imageClassesList,
                                "hu",
                                resources
                            )
                        }  // cannot be cancelled but I don't know why
            
                  ...
             } 
    }



fun translateList(originalTextsList: List<String>, targetLanguage: String, resources: Resources): List<String> {
        val translatedTextsList = mutableListOf<String>()
        try {
            val translate = getTranslateService(resources)
            val translation = translate?.translate(originalTextsList, Translate.TranslateOption.targetLanguage(targetLanguage), Translate.TranslateOption.model("base"))
            if (translation != null) {
                for(t in translation) {
                    translatedTextsList.add(t.translatedText)
                }
            }
        }
        catch (e: TranslateException) {
            e.printStackTrace()
        }
        return translatedTextsList
    }
Botond Sulyok
  • 271
  • 3
  • 14
  • 2
    For a timeout to work, the function calls inside the `withTimeout` block have to be suspend functions that cooperate with cancellation. If the API doesn't provide a Kotlin suspend function for making an async call, you can create your own using `suspendCancellableCoroutine`. But I'm not familiar with Google Cloud Translate to know what's available to you to build this. – Tenfour04 Jan 13 '21 at 22:08
  • 2
    [Coroutine cancellation is cooperative](https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html#cancellation-is-cooperative) your synchronous block of code will not be interrupted because its not aware that coroutine scope its running is has been canceled. – Pawel Jan 13 '21 at 22:10

1 Answers1

0

Take a look at withTimeoutOrNull documentation:

Runs a given suspending block of code inside a coroutine with a specified timeout and returns null if this timeout was exceeded

It means your translateList function need to be suspending function.

Here is a well tutorial explaining how to convert callback function to suspend function.

Kirill Kitten
  • 1,759
  • 1
  • 4
  • 5