我下面有三个片段
fun main() = CoroutineScope(Dispatchers.IO).launch { runMe() }
fun rumMe() = doSomething() fun main() = CoroutineScope(Dispatchers.IO).launch { runMe() }
suspend fun rumMe() = doSomething() fun main() = CoroutineScope(Dispatchers.IO).launch { runMe() }
suspend fun rumMe() = withContext(Dispatchers.Default) { doSomething() }我看到它们在与主线程不同的线程中启动,并且是异步运行的,而不是阻塞主线程。
我想知道他们有什么不同?如果它们都是一样的,那么1是最好的。如果没有,我应该什么时候使用2或3?
我试着读了这个,但是https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761看不清楚
发布于 2019-08-15 09:23:45
1和2是相同的。您必须向函数中添加suspend修饰符,只有当它使用协同操作时才能这样做。
第一和第三种情况的区别:
fun main() = CoroutineScope(Dispatchers.IO).launch {
// io thead executor
runMe()
}
// still io thread executor
fun rumMe() = doSomething()
fun main() = CoroutineScope(Dispatchers.IO).launch {
// io thead executor
runMe()
}
suspend fun rumMe() = withContext(Dispatchers.Default) {
// default/cpu thead executor
doSomething()
}发布于 2019-08-19 10:09:32
通过向函数添加suspend修饰符,允许函数使用另一个挂起函数。例如,如果runMe()函数使用挂起延迟,则使该函数可挂起是合理的。请参阅你的第一个协同线文档部分。
悬置函数与普通函数的另一个主要区别是悬置函数可取消。让我们看一下Android示例:
class MyViewModel : BaseViewModel() {
init {
viewModelScope.launch {
val firstPart = loadFirstPartOfData()
val secondPart = loadSecondPartOfData(firstPart)
...
}
}
suspend loadFirstPartOfData() = withContext(Dispatchers.IO) { ... }
suspend loadSecondPartOfData(firstPartOfData: FirstPartOfData) {
// some UI thread safe calculations
return withContext(Dispatchers.IO) {
// network request here
}
}
}假设视图(Android活动)加载数据以显示它。如果活动在加载数据的第二部分之前关闭,则加载第二部分是浪费的。但是,因为loadSecondPartOfData()函数是挂起的,所以它检查作用域是否是活动的,如果作用域不是活动的,则不会执行该函数。
还请注意函数如何使用withContext(Dispatchers.IO)。函数从viewModelScope.launch调用,默认情况下使用Dispatchers.Main (UI线程),但是从UI线程调用函数是安全的,因为函数显式地选择了执行上下文。在调用函数时不担心当前线程时,编写挂起函数的方法是正确的。是关于你的第三个问题。
在您的示例中,第一个片段可以工作,但是在一个真正的应用程序中,就像往常一样,事情会变得更加复杂。
https://stackoverflow.com/questions/57507224
复制相似问题