戻り値を持つコルーチンメソッドを作成したいです。
例えば)
fun funA() = async(CommonPool) {
return 1
}
fun funB() = async(CommonPool) {
return 2
}
fun sum() {
launch {
val total = funA().await() + funB().await()
}
}
Sumメソッドで合計を返したい場合、どうすればよいですか?
お気に入り、
fun sum(): Int {
launch {
val total = funA().await() + funB().await()
}
return total
}
正確にInt
を返すには、コルーチンの世界から抜け出す必要があり、それがrunBlocking
の目的です。
fun sum(): Int = runBlocking {
funA().await() + funB().await()
}
コルーチンガイドの ブロッキングおよびノンブロッキングワールドのブリッジング 、および サスペンド機能の作成 を参照してくださいsum
insideコルーチンを使用します。
それを達成する別の方法を追加します。
fun sum(): Int {
var sum: Int = 0
runBlocking {
val jobA = async { funA() }
val jobB = async { funB() }
runBlocking{
sum = jobA.await() + jobB.await()
}
}
return sum
}
suspend fun funA(): Int {
return 1
}
suspend fun funB(): Int {
return 2
}
この質問に答えるのは遅いかもしれませんが、うまくいけば誰かがそれを役に立つと思うでしょう。以下のコードスニペットは、3つの値A + B + Cの合計を計算します。各値は、独自のバックグラウンドスレッドで並行して個別に計算され、その後、すべての中間結果が1つの最終結果に統合され、メインスレッドに返されて画面に表示されます。
したがって、最終値を計算するのに5秒かかり(10秒= 2 + 3 + 5ではない)、結果は明らかに6であり、非ブロッキングです。メインスレッドはsum()の実行が完了していない間に他のイベントを処理できます。
suspend fun sum(scheduler: ThreadPoolExecutor): Int = coroutineScope {
withContext(scheduler.asCoroutineDispatcher()) {
val a = async { funA() }
val b = async { funB() }
val c = async { funC() }
a.await() + b.await() + c.await()
}
}
fun funA(): Int {
Thread.sleep(2000L)
return 1
}
fun funB(): Int {
Thread.sleep(3000L)
return 2
}
fun funC(): Int {
Thread.sleep(5000L)
return 3
}
class MainActivity : AppCompatActivity(), View.OnClickListener {
private val tripletsPool = ThreadPoolExecutor(3, 3, 5L, TimeUnit.SECONDS, LinkedBlockingQueue())
...
override fun onClick(view: View?) {
if (view == null) {
return
}
when (view.id) {
R.id.calculate -> {
GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT) {
progressBar.visibility = View.VISIBLE
result.setText("${sum(tripletsPool)}")
progressBar.visibility = View.GONE
}
}
}
}
}
私はあなたの仕事を編集し、funAとfunBをサスペンド関数に変更し、合計演算子の関数を作成し、この関数のメイン関数を呼び出します:
suspend fun funA(): Int{
return 1
}
suspend fun funB(): Int {
return 2
}
fun sum() = runBlocking{
val resultSum = async { funA.await() + funB.await() }
return resultSum
}
fun main() = runBlocking{
val result = async { sum() }
println("Your result: ${result.await()}")
}
それが役立つことを願っています
これは、Roomデータベースから電話番号を削除しようとしたときにブール値を返すための方法です。達成しようとしているものに同じパターンを使用できます。私のビューモデルでは:
private var parentJob = Job()
private val coroutineContext: CoroutineContext get() = parentJob + Dispatchers.Main
private val scope = CoroutineScope(coroutineContext)
suspend fun removePhoneNumber(emailSets: EmailSets, personDetails: PersonDetails) : Boolean {
var successReturn = false
scope.async(Dispatchers.IO) {
val success = async {removePhoneNumbersAsync(emailSets,personDetails)}
successReturn = success.await()
}
return successReturn
}
fun removePhoneNumbersAsync(emailSets: EmailSets, personDetails : PersonDetails):Boolean {
var success = false
try {
val emailAddressContact = EmailAddressContact(emailSets.databaseId, personDetails.id, personDetails.active)
repository.deleteEmailAddressContact(emailAddressContact)
val contact = Contact(personDetails.id, personDetails.personName, personDetails.personPhoneNumber, 0)
repository.deleteContact(contact)
success = true
} catch (exception: Exception) {
Timber.e(exception)
}
return success
}
私の活動では:
runBlocking {
if (v.tag != null) {
val personDetails = v.tag as PersonDetails
val success = viewModel.removePhoneNumber(emailSets,personDetails)
if (success) {
val parentView = v.parent as View
(parentView as? TableRow)?.visibility = View.GONE
val parentViewTable = parentView.parent as ViewGroup
(parentViewTable as? TableLayout)
parentViewTable.removeView(parentView)
}
}
}