【问题标题】:Using coroutines to write to a log file without loosing the order the logs are in使用协程写入日志文件而不丢失日志的顺序
【发布时间】:2020-05-08 12:14:36
【问题描述】:

我创建了一个自定义记录器来将我的所有日​​志写入文件以及 android 日志。由于文件写入是一个阻塞操作,我现在想让文件写入与 Kotlin 协程异步。仅将写入包装在协程中是行不通的,因为随后某些日志会被切换并且不会以正确的顺序写入文件。如何确保日志是按顺序写入的,同时不会因文件操作阻塞主线程,最好使用 Kotlin 协程?

【问题讨论】:

  • 您可以使用channels 作为日志队列
  • 您能详细说明一下吗?我今天早些时候也找到了它们,但我不太明白在这种情况下我应该如何使用它们。我是否有一个无限的协程读取通道并在读取后写入文件,以及 log 方法启动一个写入该通道的协程?我的印象是协程不应该是无限的。

标签: android asynchronous kotlin logging kotlin-coroutines


【解决方案1】:

@IR42 说的对,你应该为此使用频道。

使用Channel 并创建一个暂停的协程并等待通道的发送者发送日志(字符串或其他)。

使用默认通道RendezvousChannel,当发送者发送日志时,等待的协程恢复,如果另一个发送者发送消息,则下一个发送者被挂起,直到等待的协程从通道中提取日志。

RendezvousChannel 使用示例

val channel = Channel<String>()    // Channel of Strings
val sendChannel: SendChannel<String> = channel  // Hide that this instance can receive, store this in order to send to this channel

scope.launch(Dispatchers.IO) {
    while (!channel.isClosedForReceive) {
        val log = channel.receive()
        // process the log
    }
}

// Somewhere else
sendChannel.send("Test Log")

【讨论】:

  • 如果两个发送者调用send 方法并且都因为接收协程忙于保存以前的日志而被挂起怎么办? receive 是否按正确的顺序排列它们?
  • @EmilS。编辑了处理频道关闭的答案。 Here is tesing 为此,它可以完美地按顺序接收。输出不会立即在 Playground 的控制台中打印。您可以复制代码并在您的 IDE 中对其进行测试,每行将每 100 毫秒打印一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
  • 2015-07-03
  • 2014-09-11
  • 1970-01-01
相关资源
最近更新 更多