Объявление метода kotlin async {}

Мне было интересно, какое объявление будет правильным для длительной задачи.

suspend fun methodName(image: Bitmap?): String? = async {
   // heavy task
}.await()

ИЛИ ЖЕ

fun methodName(image: Bitmap?): String? {
   //heavyTask
}

И в коде использовать

async{
   methodName()
}.await()

Первый ограничивает выполнение тяжелых операций в фоновом потоке всегда. Итак, это безопасно (в том смысле, что он будет запускаться в фоновом потоке, так что новые разработчики обязательно будут использовать его в приостановленной конструкции).

Какой подход лучше?

3
0
681
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Рассмотрите возможность использования withContext() вместо async{}.await() в вашем случае.

Что касается вашего вопроса, ИМХО, лучше использовать такую ​​конструкцию:

suspend fun methodName(image: Bitmap?): String? = withContext(CommonPool) {
   // heavy task
}

Вопрос в том, должен ли я отдавать контроль «выполнять тяжелую задачу, не зависящую от пользовательского интерфейса, в любом потоке, разработчику» или я не должен.

Viking93 19.06.2018 13:23

@ Viking93 зависит от того, что вы пытаетесь сделать. Если вы создаете общедоступный API библиотеки, лучше делегировать работу с потоками разработчику, потому что вы не должны заставлять других разработчиков использовать Kotlin, сопрограммы и т. д. В противном случае, если этот код будет использоваться только в вашей команде, мой пример - это то, что вам нужно, потому что он использует ваш стек технологий и помогает избежать возможных проблем с потоками (вы можете указать контекст сопрограммы только один раз).

Nick 19.06.2018 13:28
Ответ принят как подходящий

Я считаю, что ключевое слово suspend является серьезным предупреждением для пользователя, чтобы предотвратить использование определенной функции в конфиденциальных потоках. Но так бывает не всегда. как сказано в документация сопрограмм:

the library can decide to proceed without suspension, if the result for the call in question is already available

Если «тяжелая задача» должна быть простой. (пример: копирование файла) Лично я просто добавляю приостановку функции без создания сопрограммы. Пользователь сам отвечает за то, где будет вызвана эта функция.

@Throws(IOException::class)
suspend fun copy(input: File, output: File) {
   //copying
}

Если «тяжелая задача» состоит из других функций suspend. Предупреждение - это обычно couroutineContext в параметре функции. А внутри он использует такие функции, как withContext().

withContext : suspends until it completes, and returns the result

@Throws(IOException::class)
suspend fun copyMultiple(context: CoroutineContext, pairFiles: List<Pair<File, File>>) {
    pairFiles.forEach { (input, output) ->
        withContext(context) { 
            copy(input, output)
        }
    }
}

Другие вопросы по теме