막무가내 삽질 블로그
코루틴 제어 본문
728x90
코루틴을 잘활용할려면 결과를 반환 받아서 처리를 하고 작업의 취소까지도 완벽하게 해줘야한다.
fun main() = runBlocking {
val job = launch {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancel() // cancels the job
job.join() // waits for job's completion
println("main: Now I can quit.")
}
0.5초 간격으로 문자열을 1000회 출력하는 블록이다. 블록이 시작한 후 1.3초가 지나면 코루틴을 취소한다.
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (i < 10) { // computation loop, just wastes CPU
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
1.3초가 지난 후에 코루틴 블록이 해제가 되어야 하지만 cancelAndJoin함수로 인해 블록이 완료될때 까지 기다렸다 종료가 된걸 확인할 수 있다.
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (isActive) { // cancellable computation loop
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
CoroutineScope의 확장 프로퍼티 isActive로 사용하여 코루틴의 취소 여부를 확인할 수 있다.
fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
println("job: I'm running finally")
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
try-finallyfh 블록을 처리하면 종료될 때 finally블록이 실행되는 걸 볼 수 있다.
fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
withContext(NonCancellable) {
println("job: I'm running finally")
delay(1000L)
println("job: And I've just delayed for 1 sec because I'm non-cancellable")
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
만약 finally에서 리소스 사용이 완료될때 까지 대기 해야 한다고하면 delay함수로 사용하면 안된다. 이유는 코루틴 블록 취소에 영향을 받기 때문에 withContext()함수를 사용해야한다.
fun main() = runBlocking {
withTimeout(1300L) {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
}
}
withTimeout() 함수를 사용해 작업을 취소할 수도 있다. 하지만 이 코드를 사용하면 CancellationException이 발생하기 때문에 앱이 강제로 중지된다. 따라서 withTimeoutOrNull()함수를 사용하는 것이 좋다.
fun main() = runBlocking {
val result = withTimeoutOrNull(1300L) {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
"Done" // will get cancelled before it produces this result
}
println("Result is $result")
}
'Android' 카테고리의 다른 글
Invoke-customs are only supported starting with Android O (--min-api 26) (0) | 2020.05.26 |
---|---|
Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to (0) | 2020.05.14 |
코틀린 코루틴 기초 (0) | 2020.05.10 |
안드로이드 디버깅 with Wifi (android adb wifi) 하는 법 (Mac) (0) | 2020.04.17 |
Adobe XD 에서 안드로이드로 이미지 보내기 (0) | 2020.04.15 |
Comments