3
如何向多个接收方发出“财产”变更信号?财产变更通知
与您将如何在Qt中定义属性并使用通知信号类似。
E.g.如果你想象一些需要以多种方式显示的价值,比如可以同时显示为进度条和文本%的进度值,当底层值发生变化时两者都需要更新。
如何向多个接收方发出“财产”变更信号?财产变更通知
与您将如何在Qt中定义属性并使用通知信号类似。
E.g.如果你想象一些需要以多种方式显示的价值,比如可以同时显示为进度条和文本%的进度值,当底层值发生变化时两者都需要更新。
一种方法是使用channels。
// The variable or property that is listened:
var i int
// Slice of all listeners
var listeners []chan int
func GetChan() chan int {
listener := make(chan int, 5)
listeners = append(listeners, listener)
return listener
}
每当你:
你的其管理/改变需要被听取可以提供GetChan()
函数返回在其上的修改(例如,新的值)将被广播的信道的属性或变量中央代码改变变量/属性,你需要广播的变化:
func Set(newi int) {
i = newi
for _, ch := range listeners {
ch <- i
}
}
和听众需要“听”为改变事件,这可以通过一个for range
环路由返回的通道上完成:
func Background(name string, ch chan int, done chan int) {
for v := range ch {
fmt.Printf("[%s] value changed: %d\n", name, v)
}
done <- 0
}
这里是主程序:
func main() {
l1 := GetChan()
l2 := GetChan()
done := make(chan int)
go Background("B1", l1, done)
go Background("B2", l2, done)
Set(3)
time.Sleep(time.Second) // Wait a little
Set(5)
// Close all listeners:
for _, listener := range listeners {
close(listener)
}
// Wait 2 background threads to finish:
<-done
<-done
}
,其输出:
[B1] value changed: 3
[B2] value changed: 3
[B1] value changed: 5
[B2] value changed: 5
您可以尝试在Go Playground完整的程序。
谢谢,正在思考这些问题,但想知道是否有一些标准或惯用的方法来做到这一点。 FWIW我玩了一些,并且制作了一个封装的PropertyInt类型,并添加了一个方法来删除侦听器,尽管我怀疑添加/删除侦听器需要锁定才能完全线程安全:http://play.golang.org/p/41ygGZ- QaB – pjoe
@pjoe是的,下一步就是做到这一点:用方法创建一个PropInt类型,就像你一样。我排除它只显示原则。正如你所提到的,锁定也是必要的,这就是为什么在我的例子中,我开始修改属性之前“预先创建”了侦听器。 – icza
这里掩盖的一个问题是阻止频道。上面的信道长度为5,但如果接收机消失,它将填满并阻止“Set”。避免这种情况的一个策略是让客户端提供通道(无论适合他们的缓存大概是0还是1),并让服务通过非阻塞发送跳过任何完整/未准备好的通道(丢弃事件)。 –