标签: coroutine

协程 WaitForSeconds 受 timeScale 影响

我正在为我的 UI 元素制作一个简单的动画。

我有一个动画组件,它有 2 个不同的动画 - ZoomIn 和 ZoomOut。

每当需要在屏幕上显示 UI 元素(例如按钮)时,就会显示这些动画。

我通常更喜欢在不显示时停用游戏对象。

我为动画编写了以下方法:

私人 IEnumerator ToggleObjectWithAnimation (GameObject gameObj) {
        Animator gameObjectAnimator = gameObj.GetComponent(); // Animator 设置为未缩放时间
        如果(gameObj.activeSelf == false){
            gameObj.transform.localScale = new Vector3 (0, 0, 1.0f);
            gameObj.SetActive (true);
            gameObjectAnimator.SetTrigger("ZoomIn");
            yield return new WaitForSeconds (0.5f);
        } else if(gameObj.activeSelf == true) {
            gameObjectAnimator.SetTrigger("ZoomOut");
            yield return new WaitForSeconds (0.5f);
            gameObj.SetActive (false); // 当时间刻度 = 0 时代码不执行
        }
        收益率返回空;
}

该代码在大多数屏幕上都可以正常工作,但是当我使用 timescale = 0 暂停游戏时会出现问题。

当 timescale 为 0 时,gameObj.SetActive (false) 行不起作用。

c# coroutine unity-game-engine

3
推荐指数
1
解决办法
1761
查看次数

Kotlin 中的延迟函数内部是如何工作的?

我一直在尝试了解 Kotlin 协程是如何工作的,我遇到了这个delay函数。

我对这部作品的理解是,

  • delay挂起当前线程,与 不同的是sleep,该线程不消耗 CPU 周期并被释放以执行其他任务。
  • 这是如何工作的,延迟函数之后的代码被捕获为 lambda(Continuation),并且可以在给定的时间段后由不同的线程执行。
  • 该实现似乎类似于 Javascript 的执行模型,其中该delay函数使延续存储在某种任务队列中并释放当前线程。指定时间过后,此任务将安排在可用线程上。

我的理解正确吗?此外,调用delay的线程与执行调用delay.

谢谢!

asynchronous coroutine kotlin kotlin-coroutines

3
推荐指数
1
解决办法
667
查看次数

Kotlin 挂起功能是否在单独的线程上运行?

挂起功能在单独的线程上运行?如果不是,那么性能优势是什么?

suspend fun requestToken():Token {..}  // takes 2 sec to complete
suspend fun createPost (token:Token){..} // takes 3 sec to complete

 suspend fun postItem() {
    val token = requestToken()
    val post =createPost(token)
    processPost(post)
  }
Run Code Online (Sandbox Code Playgroud)

因此,当我们到达processPost(post)并且如果挂起函数没有在单独的线程上运行,那么我们必须等待requestToken()createPost(token)方法完成(即 2+3=5 秒)。根据作者的说法,暂停是异步的,但是如果我们没有产生任何新线程,那么我们如何实现异步行为?

coroutine kotlin kotlinx.coroutines

3
推荐指数
1
解决办法
1326
查看次数

协程是将工作添加为另一个工作的正确方法吗?

鉴于我们有job1 : Job并且job2 : Job我们想要创建job2一个子节点job1(它们单独创建没有关系)。

声明这种关系的正确方法是什么?以便job1取消时间job2也取消...

我试过了,job1.attachChild(e1.job2 as ChildJob)但这是内部 api。当我从 job1 协程启动 job2 时,我不想做一些 hack。

coroutine kotlin kotlinx.coroutines kotlin-coroutines

3
推荐指数
1
解决办法
785
查看次数

Kotlin 协程比线程花费的时间更长

我是 Kotlin 和协程的新手,我正在尝试了解协程 API,所以我很可能做错了什么。所以我有某种对象的列表,我试图对这些对象中的每一个应用一些长时间运行的处理。

val listOfFoos = listOf(Foo(1), ..., Foo(n))
listOfFoos.forEach { longRunningJob(it) }

fun longRunningJob(foo: Foo) {
    runBlocking{
        delay(2000) //hardcoded delay for testing
    }
    //do something else
}
Run Code Online (Sandbox Code Playgroud)

当然,这是并发运行它的完美候选者,所以这里使用的是好的旧线程:

listOfFoos.map { thread(start = true) { longRunningJob(it) } }.forEach { it.join() }
Run Code Online (Sandbox Code Playgroud)

当我测量它的执行时间时,它measureTimeMillis给了我大约 2 秒的时间,这看起来非常好,因为每个都longRunningJob并行运行。但是协程要好得多,因为它没有用于上下文切换的线程那样的开销。所以这是我使用协程的实现:

val deferredResults =
    listOfFoos.map { GlobalScope.async { longRunningJob(it) } }
runBlocking {
    deferredResults.awaitAll()
}
Run Code Online (Sandbox Code Playgroud)

但是这个实现在大约 4 秒内完成了执行,这根本不是我所期望的,如果我向列表中添加更多元素,执行时间也会增加。

那么我在这里做错了什么?

concurrency coroutine kotlin kotlin-coroutines

3
推荐指数
1
解决办法
969
查看次数

在同一线程上调用新协程时如何取消旧协程

目前我有这个代码块。

如果用户停留在同一个 Fragment 上,我会apiGetObject从 API获取并且我想用 来更新它resetTime - current(请注意,该值将始终为 3 分钟)。

此代码将延迟该needReload.value = true时间。

GlobalScope.launch(Dispatchers.Main) {
    apiGetObject.value?.resetTime?.let {
        if (it - System.currentTimeMillis() > 0) {
            delay(it - System.currentTimeMillis())
        }
    }
    needReload.value = true
}
Run Code Online (Sandbox Code Playgroud)

现在我检索每个对象onResume以刷新数据(这是必须的)。因此,如果在 3 分钟窗口下恢复 Fragment,则会启动另一个协程。

=> 这使得数据

我想要的是:

我想如果有一个新的协程启动然后前一个被取消/销毁。有没有办法做到这一点(欢迎这个协程的其他解决方案)

注意:我将 MVVM 与 LiveData 一起使用,我得到了apiGetObjectRetrofit 和 RX

multithreading android coroutine kotlin kotlin-coroutines

3
推荐指数
1
解决办法
1730
查看次数

如何使用 Kotlin 延迟加载协程刷新 ViewModel 数据?

我正在尝试在我正在构建的天气应用程序中实现 SwipeToRefreshLayout。当用户滑动刷新时,应该更新ViewModel中的数据,然后相应地更新视图。

这是我的 CurrentWeatherFragment 的片段:

override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this, viewModelFactory)
                .get(WeatherResponseViewModel::class.java)

        pullToRefresh.setOnRefreshListener(this)

        bindUI()
    }

    override fun onRefresh() {
        viewModel = ViewModelProviders.of(this, viewModelFactory)
                .get(WeatherResponseViewModel::class.java)

        bindUI()
        pullToRefresh.isRefreshing = false
    }

    private fun bindUI() = launch {
        val currentWeather = viewModel.weather.await()
        currentWeather.observe(this@CurrentWeatherFragment, Observer {
            if (it == null) return@Observer

            loading_icon.visibility = View.GONE

            updateLocation("Raleigh")
            updateDateToToday()
            updateTemperatures(it.currently.temperature.roundToInt(),
                    it.currently.apparentTemperature.roundToInt(),
                    it.daily.data[0].temperatureMin.roundToInt(),
                    it.daily.data[0].temperatureMax.roundToInt())
            updateDescription(it.currently.summary)
            updateEnvironmentals((it.currently.humidity * 100).roundToInt(), it.currently.windSpeed.roundToInt())
            updateWeatherIcon(it.currently.icon)
            updateTempChart(it)
            updatePrecipChart(it)
        })
    }
Run Code Online (Sandbox Code Playgroud)

我的视图模型:

class WeatherResponseViewModel (
        private val forecastRepository: ForecastRepository,
        unitProvider: UnitProvider …
Run Code Online (Sandbox Code Playgroud)

android coroutine kotlin kotlin-coroutines

3
推荐指数
1
解决办法
3418
查看次数

kotlin 协程多次启动

如何在kotlin中像多线程一样进行多次启动

我想让它first second永远同时工作!!

像这段代码...

runBlocking {

    // first
    launch{
      first()
    }

    // second
    launch{
       second()
    }
}


suspend fun first(){
    // do something 
    delay(1000L)

    // Recursive call
    first() 
}

suspend fun second(){
    // do something 
    delay(1000L)

    // Recursive call
    second() 
}
Run Code Online (Sandbox Code Playgroud)

coroutine kotlin kotlin-coroutines

3
推荐指数
1
解决办法
1998
查看次数

关于 Kotlin 协程取消的问题

我的应用程序中有一个类似于以下的代码

class MyFragment : Fragment(), CoroutineScope by MainScope() {

    override fun onDestroy() {
        cancel()
        super.onDestroy()
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        doSomething()
    }

    private fun doSomething() = launch {
        val data = withContext(Dispathers.IO) {
            getData()
        }

        val pref = context!!.getSharedPreferences("mypref", MODE_PRIVATE)
        pref.edit().putBoolean("done", true).apply()
    }
}
Run Code Online (Sandbox Code Playgroud)

在生产中,我得到很多NPEsdoSomething(),而访问context

我的假设是coroutine调用cancel()in后被取消onDestroy(),所以我没有费心检查context空值。但看起来continues即使在cancel()被调用之后也能执行。我认为这会发生,如果cancel()在完成后调用withContext和恢复之前coroutines

所以我替换doSomething()了以下内容。

    private fun doSomething() = launch …
Run Code Online (Sandbox Code Playgroud)

android coroutine kotlin

3
推荐指数
1
解决办法
2147
查看次数

Kotlin 的启动是在主线程还是后台线程中启动协程?

我试图在 Android 的后台运行一个任务,我想知道我是否需要指定GlobalScope.launch(Dispatchers.IO) { ... }或者一个简单的GlobalScope.launch { ... }就足够了。我担心的是第二种形式是在主线程还是后台/IO 线程中启动协程?


根据Android 文档

launch不带Dispatchers.IO参数。当您不传递 aDispatcher来启动时,任何从viewModelScope 运行启动的协程都在主线程中运行

根据Kotlin 文档

在 GlobalScope 中启动协程时使用的默认调度程序由 Dispatchers.Default 表示并使用共享的线程后台池,因此launch(Dispatchers.Default) { ... }使用与GlobalScope.launch { ... }.

我知道协程直到最近才处于试验阶段,Android-Kotlin 与纯 Kotlin 开发是不同的,但这些陈述对我来说似乎是矛盾的。

android jvm coroutine kotlin kotlin-coroutines

3
推荐指数
1
解决办法
788
查看次数