暂停协程直到条件成立 [英] Suspend coroutine until condition is true

查看:79
本文介绍了暂停协程直到条件成立的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用例,需要与充当服务的类建立连接和断开连接.仅在连接服务后才能对服务执行操作.服务通过回调连接或断开连接时会通知客户端:

I have a use case where I need to connect and disconnect from a class that acts as a service. Actions can be performed on the service only when the service is connected. Clients are notified when the service connects or disconnects by a callback:

class Service {

    constructor(callback: ConnectionCallback) { ... }

    fun connect() {
        // Call callback.onConnected() some time after this method returns.
    }

    fun disconnect() {
        // Call callback.onConnectionSuspended() some time after this method returns.
    }

    fun isConnected(): Boolean { ... }

    fun performAction(actionName: String, callback: ActionCallback) {
        // Perform a given action on the service, failing with a fatal exception if called when the service is not connected.
    }

    interface ConnectionCallback {
        fun onConnected() // May be called multiple times
        fun onConnectionSuspended() // May be called multiple times
        fun onConnectionFailed()
    }
}

我想使用Kotlin Coroutines为该Service类(我不控制)编写包装. 这是ServiceWrapper的骨架:

I'd like to write a wrapper for that Service class (that I don't control) using Kotlin Coroutines. Here is a skeleton of ServiceWrapper:

class ServiceWrapper {
    private val service = Service(object : ConnectionCallback { ... })

    fun connect() {
        service.connect()
    }

    fun disconnect() {
        service.disconnect()
    }

    suspend fun performActionWhenConnected(actionName: String): ActionResult {
        suspendUntilConnected()

        return suspendCoroutine { continuation ->
            service.performAction(actionName, object : ActionCallback() {
                override fun onSuccess(result: ActionResult) {
                    continuation.resume(result)
                }

                override fun onError() {
                    continuation.resumeWithException(RuntimeException())
                }
            }
        }
    }
}

如何使用协程实现此suspendUntilConnected()行为?预先感谢.

How can I implement this suspendUntilConnected() behavior using Coroutines ? Thanks in advance.

推荐答案

以下是实现它的方法:

class ServiceWrapper {
    @Volatile
    private var deferredUntilConnected = CompletableDeferred<Unit>()

    private val service = Service(object : ConnectionCallback {
        override fun onConnected() {
            deferredUntilConnected.complete(Unit)
        }

        override fun onConnectionSuspended() {
            deferredUntilConnected = CompletableDeferred()
        }
    })

    private suspend fun suspendUntilConnected() = deferredUntilConnected.await()

    ...
}

一般说明:仅仅因为该服务在某个特定时刻已连接并不能保证在您使用该服务时它仍然可以连接.

A general note: just because the service got connected at a certain point doesn't guarantee it will still be connected by the time you use it.

这篇关于暂停协程直到条件成立的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆