是否有权在非协程上下文中使用协程
is this right to use coroutines in a non coroutine context
有一个Processor
class,试图用协程替换一些代码。由于它在非协程上下文中,因此添加 val serviceScope = CoroutineScope(Dispatchers.IO + serviceJob)
并用于启动协程。
添加 CoroutineScope
,并在使用 Thread{}.start() 的地方使用 serviceScope.launch{}
。
在函数 restart() 中,它将 CountDownLatch
的使用替换为
serviceScope.launch {
withContext(Dispatchers.IO) {
doReset()
}
}
问题:这个 launch/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()
//==========>
}
}
}
我认为它使用了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
有一个Processor
class,试图用协程替换一些代码。由于它在非协程上下文中,因此添加 val serviceScope = CoroutineScope(Dispatchers.IO + serviceJob)
并用于启动协程。
添加 CoroutineScope
,并在使用 Thread{}.start() 的地方使用 serviceScope.launch{}
。
在函数 restart() 中,它将 CountDownLatch
的使用替换为
serviceScope.launch {
withContext(Dispatchers.IO) {
doReset()
}
}
问题:这个 launch/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()
//==========>
}
}
}
我认为它使用了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