首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >协同解释

协同解释
EN

Stack Overflow用户
提问于 2020-06-27 18:49:34
回答 1查看 712关注 0票数 1

阅读了很多关于这一点,但仍然有一些不清楚的东西。这句话:"coroutines允许以同步方式编写异步代码“有点让人困惑。

协作始终是异步的。他们基本上一直在线程上运行?我们应该决定哪些线程将被我们声明使用(主范围--它们运行在MainThread和CoroutinesScope上--它将运行在一些与UI线程无关的不同线程上?,ViewmodelScope --它们将运行在与视图模型相关的线程上?)

我做得对吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-28 05:02:05

大多数java世界编写异步的传统方式是使用“回调”,他们认为这是通过为成功和失败添加侦听器来编写异步任务的唯一方法。

但合作方式略有不同。实际上,您可以调用像delay(ms: Long)这样的挂起函数,这看起来并不是异步的,因为这里不涉及任何回调,但是在幕后,延续对象将代替回调,以便在需要时恢复它。

协同始终是异步的。

是的,他们是!

他们基本上一直在线程上运行?

是的,他们是!

该由我们来决定哪些线程将被我们声明使用。

是的,绝对是。它们实现结构化并发。

主范围-它们运行在MainThread上

很明显,是的。

代码语言:javascript
复制
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)

它使用上下文的dispatcher元素创建一个CoroutineScope作为Dispatchers.Main,使子线程在默认情况下被分派到主线程中(如果没有指定),并附加一个SupervisorJob,以使其他子线程不受取消一个线程的影响。

CoroutinesScope -它将在一些与UI线程无关的不同线程上运行??

不,应该将CoroutineDispatcher元素提供给CoroutineContext,以决定需要向哪个线程分派子协同,例如,有4个默认的CoroutineDispatcher:

  • Dispatchers.Main -发送到主线程(单线程)
  • Dispatchers.Default -向CommonPool发送(最大线程数与处理器中的内核相同)
  • Dispatchers.IO -向CommonPool发送(最大线程数: 64)
  • Dispatchers.Unconfined -向已注册的任何线程发送补丁(通常用于非常小的任务,并且不建议使用)

此外,您还可以使用CoroutineDispatcher制作自己的java.util.Executors

代码语言:javascript
复制
Executors.newFixedThreadPool(4).asCoroutineDispatcher() // Your own dispatcher max of 4-threads

除了Dispatcher之外,CoroutineContext中还有许多其他元素。比如: Job、CoroutineName、CoroutineInterceptor、CoroutineExceptionHandler等。我建议阅读 的文章,以便更好地直观地显示CoroutineContext.中一些最重要的元素所发生的事情。

CoroutineScope只是CoroutineContext的包装器,它本质上有助于使用launchasync启动协同线,您可以通过将CoroutineContext作为参数(如:CoroutineScope(Dispatchers.Default + Job() + CoroutineName("My Coroutine")) )来创建协同线。

+ 注: CoroutineContext的所有元素本身都是一个CoroutineContext,符号是在CoroutineContext中定义的 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/plus.html 函数的过载--基本上覆盖了来自左CoroutineContext的元素和来自右CoroutineContext的元素(如果左侧不存在元素,则只需添加它)。

ViewmodelScope -它们将运行在与视图模型相关的线程上?

ViewModelScope默认实现Dispatchers.Main来启动任务,它们可以更改UI元素,因为只有主线程才能更改UI元素。

SideNote:您可以在启动之前更改CoroutineContext元素(覆盖范围之一)。

示例:

代码语言:javascript
复制
viewModelScope.launch(Dispatchers.Default) {
    // This coroutine is launched under Dispatchers.Default (backed by a CommonPool of threads) instead of Dispatchers.Main
    // but will follow cancellation as soon as lifecycle of Activity associated is destroyed as Job element is not overriden
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62614216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档