【发布时间】:2015-03-18 14:59:05
【问题描述】:
我正在查询 SNMP,我想在数据检索完成时执行回调。为此,我使用以下代码:
def treeWalk(rootOid: String)(callback: (Seq[Tuple2[OID, Variable]]) => Unit) {//{{{
val transport = new DefaultUdpTransportMapping
val snmp = new Snmp(transport)
transport.listen
val target = new CommunityTarget
target.setCommunity(new OctetString(community))
target.setAddress(GenericAddress.parse("udp:" + address + "/161"))
target.setRetries(retries)
target.setTimeout(timeout)
target.setVersion(SnmpConstants.version2c)
val treeUtil = new TreeUtils(snmp, new DefaultPDUFactory)
var variables: Seq[VariableBinding] = List()
var _isFinished = false
val listener = new TreeListener {
def next(event: TreeEvent) = {
println("NEXT")
val vars = event.getVariableBindings
if(vars != null)
variables ++= vars
true
}
def isFinished() = _isFinished
def finished(event: TreeEvent) {
val vars = event.getVariableBindings
println("DONE")
if(vars != null)
variables ++= vars
_isFinished = true
snmp.close
callback(variables.map(v => (v.getOid, v.getVariable)))
}
}
treeUtil.walk(target, Array(new OID(rootOid)), null, listener)
}
我没有收到任何错误或异常,但是我从未在 next() 和 finished() 中看到打印行,而且回调也没有执行。我做错了什么,我应该如何将事件侦听器挂钩?
PS:单行同步版本返回数据就好了……
我正在使用 Scala 2.11.6 和 SNMP4J 2.3
【问题讨论】:
-
我对 SNMP 不熟悉,但如果它和我见过的大多数回调一样,那么您在哪里等着让调用时间完成以便可以执行回调?
-
我正在调用您在此处看到的方法,其中“println”作为回调函数。据我了解,回调应该是方法之后调用堆栈中的下一个条目。所以这意味着不涉及等待,该方法将在完成时调用它。对吗?
-
在阻塞的情况下,是的。但是,当您有一个带有回调的异步调用时,程序可以在异步操作完成之前终止。您可以通过使其休眠或以stackoverflow.com/questions/16256279/wait-for-several-futures 中显示的方式重组程序来完成此操作,以便等待方法返回。
-
基本上,主线程启动异步过程,然后用完指令,所以它终止,这会导致你程序的所有线程终止,包括任何正在运行的线程正在处理异步调用。
-
确实你是对的,最快的解决方案是 Thread.sleep 。我将在未来进一步实施它。
标签: scala asynchronous functional-programming snmp4j