我正在实现一个自定义 Kotlin CoroutineScope,用于处理通过 WebSocket 连接接收、处理和响应消息。该作用域的生命周期与 WebSocket 会话相关,因此只要 WebSocket 打开,它就处于活动状态。作为协程作用域上下文的一部分,我安装了一个自定义异常处理程序,如果存在未处理的错误,该处理程序将关闭 WebSocket 会话。是这样的:
val handler = CoroutineExceptionHandler { _, exception ->
log.error("Closing WebSocket session due to an unhandled error", exception)
session.close(POLICY_VIOLATION)
}
Run Code Online (Sandbox Code Playgroud)
我惊讶地发现异常处理程序不仅接收异常,而且实际上为所有未处理的可抛出对象(包括Error. 我不确定应该如何处理这些,因为我从Java API 文档Error中知道“一个Error[...] 表明合理的应用程序不应尝试捕获的严重问题”。
我最近遇到的一个特殊情况是OutOfMemoryError由于会话处理的数据量所致。OutOfMemoryErrormy 收到了,这CoroutineExceptionHandler意味着它已被记录并且 WebSocket 会话已关闭,但应用程序继续运行。这让我感到不舒服,因为我知道OutOfMemoryError在代码执行期间的任何时候都可以抛出 an ,从而导致应用程序处于不可恢复的状态。
我的第一个问题是:为什么 Kotlin API 选择将这些错误传递给CoroutineExceptionHandler我(程序员)来处理?
我的第二个问题是:我处理它的适当方法是什么?我至少可以想到三个选择:
OutOfMemoryError在 Java 中捕获的问题的回答,该问题强烈建议不要尝试从此类错误中恢复。Error正常(或框架)代码的任何其他情况下通常会做的事情,因为它最终会导致 …我正在编写一个解码器,它将接收一系列字节缓冲区并将内容解码为单个String. 可以有任意数量的字节缓冲区,每个缓冲区包含任意数量的字节。缓冲区不一定在字符边界上分割,因此根据编码,它们可能在开头或结尾包含部分字符。这就是我想要做的,StringByteStreamDecoder我需要编写的新类在哪里。
suspend fun decode(data: Flow<ByteBuffer>, charset: Charset): String {
val decoder = StringByteStreamDecoder(charset)
data.collect { bytes ->
decoder.feed(bytes)
}
decoder.endOfInput()
return decoder.toString()
}
Run Code Online (Sandbox Code Playgroud)
最简单的方法是将所有字节缓冲区收集到一个字节数组中。我拒绝了这种方法,因为它具有显着的内存开销。它需要为完整消息分配空间至少两次:一次为原始字节,一次为解码字符。这是我的简单实现,使用 aByteArrayOutputStream作为扩展字节缓冲区。
class StringByteStreamDecoder(private val charset: Charset) {
private val buffer = ByteArrayOutputStream()
fun feed(data: ByteBuffer) {
if (data.hasArray()) {
buffer.write(data.array(), data.position() + data.arrayOffset(), data.remaining())
} else {
val array = ByteArray(data.remaining())
data.get(array)
buffer.write(array, 0, array.size)
}
}
fun endOfInput() {
buffer.flush()
}
override fun toString(): String {
return …Run Code Online (Sandbox Code Playgroud) 标题可能会产生误导,但我真的不知道它叫什么.我对此感到抱歉 :(
所以,我有一个像这样的数组
$start = array(
array('waterpark'),
array('spain','greece'),
array('1','2','3','4'),
);
Run Code Online (Sandbox Code Playgroud)
我如何将该数组转换为这样
$output = array(
array('waterpark', 'spain', '1'),
array('waterpark', 'spain', '2'),
array('waterpark', 'spain', '3'),
array('waterpark', 'spain', '4'),
array('waterpark', 'greece', '1'),
array('waterpark', 'greece', '2'),
array('waterpark', 'greece', '3'),
array('waterpark', 'greece', '4'),
);
Run Code Online (Sandbox Code Playgroud)
先感谢您
我正在尝试做一个简单的if语句使用?图案.导致"不是声明" - 错误.有人可以向我解释为什么使用正常的if语句不会发生这种情况?
错误:
cursor.isNull(0) ? insert_SQL_RSServer.bindNull(0) : insert_SQL_RSServer.bindLong(0, cursor.getLong(0)); // id
Run Code Online (Sandbox Code Playgroud)
没错误:
if(cursor.isNull(0))
insert_SQL_RSServer.bindNull(0);
else
insert_SQL_RSServer.bindLong(0, cursor.getLong(0));
Run Code Online (Sandbox Code Playgroud)
这是完全相同的行为....
kotlin ×3
android ×1
arrays ×1
bytebuffer ×1
java ×1
jvm ×1
kotlin-flow ×1
nio ×1
nonblocking ×1
php ×1