это право использовать сопрограммы в не сопрограммном контексте - PullRequest
1 голос
/ 03 июля 2019

Имея класс Processor, пытаюсь заменить часть кода сопрограммами.Поскольку он находится в контексте без сопрограмм, поэтому val serviceScope = CoroutineScope(Dispatchers.IO + serviceJob) добавляется и используется для запуска сопрограмм.

Добавлен CoroutineScope и используется serviceScope.launch{} в месте, где использовался Thread {}. Start ().

Внутри функции restart () она заменила использование CountDownLatch на

serviceScope.launch {
                withContext(Dispatchers.IO) {

                    doReset()
                }
            }

Вопрос: этот запуск / withContext фактически не останавливает выполнение кода следующего if (!conDoProcess)- поэтому он не может сделать то, что делал latch.

как правильно остановить выполнение кода до doReset().сделано?

Еще один вопрос, когда утилизируйте этот Processor объект, который он вызывает serviceScope.cancel(),

В чем разница, если вызов с serviceJob.cancel()?

class Processor {

    private val serviceJob = Job()
    private val serviceScope = CoroutineScope(Dispatchers.IO + serviceJob)

            .........

    /* return false if the it does not start the processing */
    fun restart(): Boolean {

        synchronized(_lock) {

            .........

            // 1.old code using latch to wait

            /******************
            val latch = CountDownLatch(1)
            streamThreadPoolExecutor.execute {

                doReset()  //

                latch.countDown()
            }
            latch.await(3, TimeUnit.SECONDS) // wait at most for 3 seconds if no one calls countDown

            *******************/

            // 2. change to using coroutines to suspend

            serviceScope.launch {
                withContext(Dispatchers.IO) {

                    doReset()
                }
            }

            // wait until reset is done
            if (!conDoProcess) {// the doRest() should update conDoProcess
                return false
            }

            for (i in providers.indices) {
                val pr = provider[i]
                serviceScope.launch {
                    pr.doProcess()
                }
            }

            return true
        }
    }

    fun dispose() {
        synchronized(_lock) {

            .........
            serviceScope.cancel()

            // or should it use
            // serviceJob.cancel()
            //==========>
        }
    }
}

1 Ответ

0 голосов
/ 10 июля 2019

Я думаю, что он использовал serviceScope.launch неправильно, он должен включать оставшуюся часть после блокирующей части withContext(Dispatchers.IO), но внутри serviceScope.launch.

        // 2. change to using coroutines to suspend

        serviceScope.launch {
            withContext(Dispatchers.IO) {

                doReset()
            }

            // wait until reset is done
            if (!conDoProcess) {// the doRest() should update conDoProcess
              return false
            }

            for (i in providers.indices) {
              val pr = provider[i]
              serviceScope.launch {
                  pr.doProcess()
              }
            }   
        }

        return true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...