Сопрограмма приостановить функцию и блокировку вызовов - PullRequest
0 голосов
/ 16 марта 2020

Ниже приведен мой пример использования. У меня есть функция fun requestFocus эта функция, в свою очередь, вызывает функцию fun configure, которая зависит от обратного вызова из системы, следовательно, эта функция configure использует coundownlatch со счетчиком 1 и ожидает до тех пор, пока не будет сброшен в ноль при получении обратного вызова , Для этого я пометил requestFocus suspend и использую Dispatchers.IO для выполнения всех операций. Теперь есть несколько абонентов requestFocus для функции ex fun accept. Функция accept делает много вещей, и все они происходят в одном потоке. Функция accept также может быть вызвана из основного потока или службы намерений. Моя проблема в том, что функция конфигурации блокирует, я не хочу блокировать основной поток. В настоящее время функция accept выглядит следующим образом:

fun accept() {
    //do something
    requestFocus()
    // do something
}

Я не уверен, как я могу вызвать requestFocus from accept, и все операции, которые происходят после выполнения requestFocus, выполняются таким же образом. То, что я сделал в настоящее время в функции принятия, ниже

fun accept() {
    //do something
    runBlocking{
    requestFocus()
    // do something
}

Но это создает проблему, поскольку основной поток блокируется. Любое предложение, что я могу попробовать? Я изучил документацию Глобального объема и основного объема.

1 Ответ

1 голос
/ 16 марта 2020

Вы ищете withContext блок. withContext ведет себя подобно runBlocking, но вместо того, чтобы блокировать его, он приостанавливает поток.

suspend fun accept() {
    //do something on calling thread
    withContext(Dispatchers.IO){ // Changes to Dispatchers.IO and suspends the calling thread
        requestFocus() // Calls requestFocus() on Dispatchers.IO
        // do something on Dispatchers.IO
    }
    // Resumes calling thread
}

Вам необходимо вызвать accept из области сопрограмм или из другой функции приостановки. Или вы можете создать сопрограмму с launch, чтобы запустить сопрограмму:

fun accept() = launch(Dispatchers.Main) { // Starts a coroutine on the main thread
    //do something on main thread
    withContext(Dispatchers.IO){ // Changes to Dispatchers.IO and suspends the main thread
        requestFocus() // Calls requestFocus() on Dispatchers.IO
        // do something on Dispatchers.IO
    }
    // Resumes main thread
}
...