hey, I want to make a blocking function to suspend...
# coroutines
k
hey, I want to make a blocking function to suspend function, I have tried this code
Copy code
suspend fun mydelay(timeMillis: Long) {
        if (timeMillis < 0) {
            return
        }

        if (timeMillis < Long.MAX_VALUE) {
            suspendCoroutine<Unit> {
                Thread.sleep(timeMillis)
                it.resume(Unit)
            }
        }
    }
but failed in
Copy code
repeat(100) {
            launch {
                mydelay(1000)
                println("awake ${Thread.currentThread()}")
            }
        }
it can be like
delay
suspend function, how can I do it ?
a
What exactly do you want to achieve? If you only want to make a function suspend, I am assuming it does IO, you can do that with
Copy code
suspend fun doIO() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) { /* code here */ }

// If it’s something you want the result for at later in time the you can use async {} and then call .await() on it
k
actually, here I have a sync function called
download
, and I want to make it suspend so that I can launch many coroutines with running it
Copy code
repeat(1000) {
    download
}
so I similator it with
Thread.sleep
z
I think the best practice here is to just launch your coroutines from your loop without any additional context, then switching to the IO dispatcher (via withContext) should be an implementation detail of your download function. The reason is that the download function could potentially use a non-blocking api itself, which wouldn’t require switching dispatchers. If it uses a blocking api, that’s an implementation detail and the function can satisfy the “suspend functions must not block caller” contract by switching dispatchers.
plus1 2
k
heavy sigh. is there a async downloader with kotlin coroutine ? I want to check the code
z
There are tons of examples of doing various types of io with coroutines on the internet, this is a pretty common thing.
k
I don't know what's the keyword to search, may be you can help me
z
I’m not either, you’re asking a pretty general question. The thing I suggested is basically just this, adapting the code you’ve already posted:
Copy code
suspend fun downloadEverything() {
  coroutineScope {
    repeat(1000) {
      launch { download() }
    }
  }
}

suspend fun download() {
  withContext(Dispatchers.IO) {
    blockingDownloadCall()
  }
}