【发布时间】:2021-06-29 09:39:15
【问题描述】:
在我的 Android 应用程序中,我的代码应该在自己的协程中定期运行并且应该可以取消。
为此,我有以下功能:
startJob():初始化作业,设置invokeOnCompletion()并在各自的范围内启动工作循环
private fun startJob() {
if (::myJob.isInitialized && myJob.isActive) {
return
}
myJob= Job()
myJob.invokeOnCompletion {
it?.message.let {
var msg = it
if (msg.isNullOrBlank()) {
msg = "Job stopped. Reason unknown"
}
myJobCompleted(msg)
}
}
CoroutineScope(Dispatchers.IO + myJob).launch {
workloop()
}
}
workloop():主工作循环。在每次迭代中设置延迟的循环中做一些工作:
private suspend fun workloop() {
while (true) {
// doing some stuff here
delay(setDelayInMilliseconds)
}
}
myJobCompleted:做一些最终确定。现在只需记录一条消息进行测试。
private fun myJobCompleted(msg: String) {
try {
mainActivityReference.logToGUI(msg)
}
catch (e:Exception){
println("debug: " + e.message)
}
}
运行此程序并调用myJob.Cancel() 将在myJobCompleted() 中引发以下异常:
调试:只有创建视图层次结构的原始线程才能接触其视图。
我很好奇为什么这段代码没有在主线程上运行,因为startJob()是从主线程调用的?
此外:是否有类似于在c# 中使用CancellationTokenSource 的选项,其中作业不会立即取消,但可以在while 循环的每次迭代中检查取消请求?
立即中断工作,不管它在做什么(尽管它几乎总是在等待取消延迟)对我来说似乎不是一个好主意。
【问题讨论】:
标签: multithreading kotlin kotlin-coroutines