为什么我的 Go 事件每两个事件才被处理一次?

huangapple go评论65阅读模式
英文:

Why is my Go event only being handled once per two events?

问题

我有以下的settings_manager.go文件:

package main

type Settings struct {
	globalTrackingDisabled      bool
	textTracking                bool
	imageTracking               bool
	debug                       bool
	Event                       chan string
	EventTextTracking           string
	EventImageTracking          string
	EventGlobalTrackingDisabled string
	EventDebugToggled           string
}

type DefaultValues struct {
	GlobalTrackingDisabled bool
	TextTracking           bool
	ImageTracking          bool
	DebugEnabled           bool
}

func NewSettings(defaults DefaultValues) *Settings {
	return &Settings{
		globalTrackingDisabled:      defaults.GlobalTrackingDisabled,
		textTracking:                defaults.TextTracking,
		imageTracking:               defaults.ImageTracking,
		debug:                       defaults.DebugEnabled,
		Event:                       make(chan string, 1),
		EventTextTracking:           "textTracking",
		EventImageTracking:          "imageTracking",
		EventGlobalTrackingDisabled: "globalTrackingDisabled",
		EventDebugToggled:           "debugToggled",
	}
}

// 获取textTracking的当前值
func (s *Settings) TextTrackingEnabled() bool {
	return s.textTracking
}

// 获取imageTracking的当前值
func (s *Settings) ImageTrackingEnabled() bool {
	return s.imageTracking
}

// 获取globalTrackingDisabled的当前值
func (s *Settings) GlobalTrackingDisabled() bool {
	return s.globalTrackingDisabled
}

// 获取TextTrackingEnabled()的反值
func (s *Settings) TextTrackingDisabled() bool {
	return !s.TextTrackingEnabled()
}

// 获取ImageTrackingEnabled()的反值
func (s *Settings) ImageTrackingDisabled() bool {
	return !s.ImageTrackingEnabled()
}

// 获取GlobalTrackingDisabled()的反值
func (s *Settings) GlobalTrackingEnabled() bool {
	return !s.GlobalTrackingDisabled()
}

// 获取GlobalTrackingDisabled()的反值
func (s *Settings) Debug() bool {
	return s.debug
}

// SetGlobalTracking设置globalTrackingDisabled属性并触发事件
func (s *Settings) SetGlobalTracking(value bool) {
	s.textTracking = value
	s.Event <- s.EventGlobalTrackingDisabled
}

// SetTextTracking设置textTracking属性并触发事件
func (s *Settings) SetTextTracking(value bool) {
	Debug("setter to ", value, s.EventTextTracking)
	s.textTracking = value
	s.Event <- s.EventTextTracking
	Debug("Sent event %s\n", s.EventTextTracking)
}

// SetImageTracking设置imageTracking属性并触发事件
func (s *Settings) SetImageTracking(value bool) {
	s.imageTracking = value
	s.Event <- s.EventImageTracking
}

// SetDebug设置debug属性并触发事件
func (s *Settings) SetDebug(value bool) {
	s.debug = value
	s.Event <- s.EventDebugToggled
}

// DebugDisable将debug属性设置为false并触发事件
func (s *Settings) DebugDisable() {
	s.debug = false
	s.Event <- s.EventDebugToggled
}

// DebugEnable将debug属性设置为true并触发事件
func (s *Settings) DebugEnable() {
	s.debug = true
	s.Event <- s.EventDebugToggled
}

我有一个系统托盘菜单项,我希望在点击时切换TextTracking设置。

// 点击操作

go func() {
	for {
		select {
		case <-captureTextMenuItem.ClickedCh:
			Debug("菜单项被点击。新值应为", !captureTextMenuItem.Checked())
			if captureTextMenuItem.Checked() {
				settings.SetTextTracking(false)
			} else {
				settings.SetTextTracking(true)
			}
			//settings.SetTextTracking(!settings.TextTrackingEnabled())
			//Debug(settings.TextTrackingEnabled())
		}
	}
}()

以下是我处理事件的方式:

// 事件处理程序

go func() {
	for {
		select {
		case event := <-settings.Event:
			Debug("接收到事件", event)
			switch event {
			case settings.EventTextTracking:
				Debug("准备处理文本事件")
				if settings.TextTrackingEnabled() {
					Debug("启用勾选标记")
					captureTextMenuItem.Check()
				} else {
					Debug("移除勾选标记")
					captureTextMenuItem.Uncheck()
				}
			case settings.EventGlobalTrackingDisabled:
				Debug("准备处理全局跟踪器事件")
				if settings.GlobalTrackingEnabled() {
					Debug("启用全局跟踪器")
					captureTextMenuItem.Enable()
				} else {
					Debug("禁用全局跟踪器")
					captureTextMenuItem.Disabled()
				}
			default:
				fmt.Println("接收到未知事件:", event)
			}
		}
	}
}()

我遇到的问题是,每次点击菜单项时,我可以看到SetTextTracking被触发,但是我的事件处理程序只在事件触发两次时才被调用一次。

英文:

I have the following settings_manager.go

package main
type Settings struct {
globalTrackingDisabled      bool
textTracking                bool
imageTracking               bool
debug                       bool
Event                       chan string
EventTextTracking           string
EventImageTracking          string
EventGlobalTrackingDisabled string
EventDebugToggled           string
}
type DefaultValues struct {
GlobalTrackingDisabled bool
TextTracking           bool
ImageTracking          bool
DebugEnabled           bool
}
func NewSettings(defaults DefaultValues) *Settings {
return &amp;Settings{
globalTrackingDisabled:      defaults.GlobalTrackingDisabled,
textTracking:                defaults.TextTracking,
imageTracking:               defaults.ImageTracking,
debug:                       defaults.DebugEnabled,
Event:                       make(chan string, 1),
EventTextTracking:           &quot;textTracking&quot;,
EventImageTracking:          &quot;imageTracking&quot;,
EventGlobalTrackingDisabled: &quot;globalTrackingDisabled&quot;,
EventDebugToggled:           &quot;debugToggled&quot;,
}
}
// Get the current value of textTracking
func (s *Settings) TextTrackingEnabled() bool {
return s.textTracking
}
// Get the current value of imageTracking
func (s *Settings) ImageTrackingEnabled() bool {
return s.imageTracking
}
// Get the current value of globalTrackingDisabled
func (s *Settings) GlobalTrackingDisabled() bool {
return s.globalTrackingDisabled
}
// Get inverse of TextTrackingEnabled()
func (s *Settings) TextTrackingDisabled() bool {
return !s.TextTrackingEnabled()
}
// Get inverse of ImageTrackingEnabled()
func (s *Settings) ImageTrackingDisabled() bool {
return !s.ImageTrackingEnabled()
}
// Get the inverse of GlobalTrackingDisabled()
func (s *Settings) GlobalTrackingEnabled() bool {
return !s.GlobalTrackingDisabled()
}
// Get the inverse of GlobalTrackingDisabled()
func (s *Settings) Debug() bool {
return s.debug
}
// SetGlobalTracking sets the globalTrackingDisabled property and fires an event
func (s *Settings) SetGlobalTracking(value bool) {
s.textTracking = value
s.Event &lt;- s.EventGlobalTrackingDisabled
}
// SetTextTracking sets the textTracking property and fires an event
func (s *Settings) SetTextTracking(value bool) {
Debug(&quot;setter to &quot;, value, s.EventTextTracking)
s.textTracking = value
s.Event &lt;- s.EventTextTracking
Debug(&quot;Sent event %s\n&quot;, s.EventTextTracking)
}
// SetImageTracking sets the imageTracking property and fires an event
func (s *Settings) SetImageTracking(value bool) {
s.imageTracking = value
s.Event &lt;- s.EventImageTracking
}
// SetDebug sets the debug property and fires an event
func (s *Settings) SetDebug(value bool) {
s.debug = value
s.Event &lt;- s.EventDebugToggled
}
// DebugDisable sets the debug property to false and fires an event
func (s *Settings) DebugDisable() {
s.debug = false
s.Event &lt;- s.EventDebugToggled
}
// DebugEnable sets the debug property to true and fires an event
func (s *Settings) DebugEnable() {
s.debug = true
s.Event &lt;- s.EventDebugToggled
}

I have a systray menu item that I want to toggle the TextTracking setting when clicked.

// Click action

	go func() {
		for {
			select {
			case &lt;-captureTextMenuItem.ClickedCh:
				Debug(&quot;Menu item clicked. New Value should be &quot;, !captureTextMenuItem.Checked())
				if captureTextMenuItem.Checked() {
					settings.SetTextTracking(false)
				} else {
					settings.SetTextTracking(true)
				}
				//settings.SetTextTracking(!settings.TextTrackingEnabled())
				//Debug(settings.TextTrackingEnabled())
			}
		}
	}()

Here is how I am handling the event:

// event handler


	go func() {
		for {
			select {
			case event := &lt;-settings.Event:
				Debug(&quot;Received Event&quot;, event)
				switch event {
				case settings.EventTextTracking:
					Debug(&quot;Ready to do something with the text event&quot;)
					if settings.TextTrackingEnabled() {
						Debug(&quot;Enabling checkmark&quot;)
						captureTextMenuItem.Check()
					} else {
						Debug(&quot;Removing checkmark&quot;)
						captureTextMenuItem.Uncheck()
					}
				case settings.EventGlobalTrackingDisabled:
					Debug(&quot;Ready to do something with the global tracker event&quot;)
					if settings.GlobalTrackingEnabled() {
						Debug(&quot;enabling global tracker&quot;)
						captureTextMenuItem.Enable()
					} else {
						Debug(&quot;disabling global tracker&quot;)
						captureTextMenuItem.Disabled()
					}
				default:
					fmt.Println(&quot;received unknown event:&quot;, event)
				}
			}
		}
	}()

The problem that I having is each time that I click the menu item, I can see that SetTextTracking is triggered, however, my event handler is only called once every two times the event is fired.

答案1

得分: 1

因为你使用了带缓冲的通道。
当你向通道发送一个载荷时,不会发生任何事情。当你发送另一个载荷时,缓冲区将被刷新,接收方将开始运行。

尝试使用一个非缓冲的通道。

英文:

Because you use buffered channels.
You send a payload to the channel and nothing happens. When you send another payload the buffer will be flushed and the receiver side will start to run.

Try to use an unbuffered channel.

huangapple
  • 本文由 发表于 2022年12月22日 02:18:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/74880258.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定