如何等待并正确 return 来自异步协程的值
How to wait and properly return value from async coroutine
我通过单击按钮调用 function
(非暂停)。我想 运行 使用 async
协程和 return 最后计算值在 function
中循环。
我的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnCount.setOnClickListener {
var result = GlobalScope.async { dummyFoo() }
runBlocking {
Toast.makeText(this@MainActivity, result.await().toString(), Toast.LENGTH_LONG).show()
}
}
}
private fun dummyFoo() : Int {
var result : Int = 0
val waitFor = CoroutineScope(Dispatchers.IO).async {
for (i in 1..20000) {
result++
}
return@async result
}
return result
}
输出:
我在 Toast
中得到 0。
我想要 20000 Toast
。
如何让我的代码等到循环完成和结果变为 20000
并输出它?
不确定我是否明白这样做的目的,但如果这是您想要的,请将 Dispatchers.IO
替换为 Dispatchers.Unconfined
你应该在 dummyFoo() 中使用 await
private suspend fun dummyFoo() : Int {
var result : Int = 0
val waitFor = CoroutineScope(Dispatchers.IO).async {
for (i in 1..20000) {
result++
}
return@async result
}
waitFor.await()
return result
}
您似乎想在 GUI 线程之外启动一个 CPU 密集型任务,然后在 GUI 中显示结果。这是协程的一个基本用例,解决方法如下:
btnCount.setOnClickListener {
GlobalScope.launch(Dispatchers.Main) {
val result = withContext(Dispatchers.Default) {
dummyFoo()
}
Toast.makeText(this@MainActivity, result.toString(), Toast.LENGTH_LONG).show()
}
}
这伴随着通常的警告,即您不应在全局范围内启动协程,而应为相关 activity 创建一个范围。否则,即使用户离开您的应用,这些后台任务也会占用 CPU。
我通过单击按钮调用 function
(非暂停)。我想 运行 使用 async
协程和 return 最后计算值在 function
中循环。
我的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnCount.setOnClickListener {
var result = GlobalScope.async { dummyFoo() }
runBlocking {
Toast.makeText(this@MainActivity, result.await().toString(), Toast.LENGTH_LONG).show()
}
}
}
private fun dummyFoo() : Int {
var result : Int = 0
val waitFor = CoroutineScope(Dispatchers.IO).async {
for (i in 1..20000) {
result++
}
return@async result
}
return result
}
输出:
我在 Toast
中得到 0。
我想要 20000 Toast
。
如何让我的代码等到循环完成和结果变为 20000
并输出它?
不确定我是否明白这样做的目的,但如果这是您想要的,请将 Dispatchers.IO
替换为 Dispatchers.Unconfined
你应该在 dummyFoo() 中使用 await
private suspend fun dummyFoo() : Int {
var result : Int = 0
val waitFor = CoroutineScope(Dispatchers.IO).async {
for (i in 1..20000) {
result++
}
return@async result
}
waitFor.await()
return result
}
您似乎想在 GUI 线程之外启动一个 CPU 密集型任务,然后在 GUI 中显示结果。这是协程的一个基本用例,解决方法如下:
btnCount.setOnClickListener {
GlobalScope.launch(Dispatchers.Main) {
val result = withContext(Dispatchers.Default) {
dummyFoo()
}
Toast.makeText(this@MainActivity, result.toString(), Toast.LENGTH_LONG).show()
}
}
这伴随着通常的警告,即您不应在全局范围内启动协程,而应为相关 activity 创建一个范围。否则,即使用户离开您的应用,这些后台任务也会占用 CPU。