如何在fileevent中接收proc返回数据

时间:2013-06-21 07:09:42

标签: tcl

我通过fileevent调用proc。 proc返回一行od数据。 如何接收这些数据? 我写的以下代码用于在数据可用时从管道接收数据。我不想通过使用直接获取阻止。

proc GetData1 { chan } {
    if {[gets $chan line] >= 0} {
        return $line
    }
}

proc ReadIO {chan {timeout 2000} } {
    set x 0
    after $timeout {set x 1}
    fconfigure $chan -blocking 0  

    fileevent $chan readable [ list GetData1 $chan ] 
    after cancel set x 3
    vwait x
    # Do something based on how the vwait finished...
    switch $x {
       1 { puts "Time out" }
       2 { puts "Got Data" }
       3 { puts "App Cancel" }
       default { puts "Time out2  x=$x" }
    }
    # How to return data from here which is returned from GetData1
}

ReadIO $io 5000

# ** How to get data here which is returned from GetData1 ? **

1 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点,因为有Tcl程序员。本质上,你不应该使用return来从你的fileevent处理程序传回数据,因为它不是以通常的方式call,所以你可以得到它返回的内容。

以下是一些可能的方法。

免责声明这些都没有经过测试,而且我很容易输入错误,所以请小心点心!

1)获取你的fileevent处理程序以写入一个全局可靠的:

proc GetData1 {chan} {
    if {[gets $chan line]} >= 0} {
        append ::globalLine $line \n
    }
}

.
.
.

ReadIO $io 5000

# ** The input line is in globalLine in the global namespace **

2)将全局变量的名称传递给fileevent处理程序,并将数据保存在那里

proc GetData2 {chan varByName} {
    if {[gets $chan line]} >= 0} {
        upvar #0 $varByName var
        append var $line \n
    }
}

fileevent $chan readable [list GetData1 $chan inputFromChan]

.
.
.

ReadIO $chan 5000

# ** The input line is in ::inputFromChan **

这里变量的一个很好的选择可能是由$ chan索引的数组,例如fileevent $chan readable [list GetDetail input($chan)]

3)定义某种类来管理你的内部存储数据的通道,并有一个成员函数来返回它

oo::class create fileeventHandler {
    variable m_buffer m_chan

    constructor {chan} {
        set m_chan $chan
        fileevent $m_chan readable [list [self object] handle]
        set m_buffer {}
    }

    method data {} {
        return $m_buffer
    }

    method handle {} {
        if {[gets $m_chan line]} >= 0 {
            append m_buffer $line \n
        }
    }
}

.
.
.

set handlers($chan) [fileeventHandler new $chan];  # Save object address for later use

ReadIO $io 5000

# Access the input via [handlers($chan) data]