本文介绍了为什么 NotifyIcon 没有设置 SynchronizationContext?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个 WinForms 程序:

Consider this WinForms program:

Module Main
    Dim notifyicon As New System.Windows.Forms.NotifyIcon
    'Dim dummycontrol As New System.Windows.Forms.Control

    Public Sub Main()
        If (System.Threading.SynchronizationContext.Current Is Nothing) Then
            MessageBox.Show("Nothing")
        Else
            MessageBox.Show("Something")
        End If
    End Sub
End Module

NotifyIcon 是一个 WinForm 控件,并且需要一个消息循环,那么为什么声明 dummycontrol(或任何 WinForms 控件)会设置一个 SynchronizationContext,而 NotifyIcon 没有?

NotifyIcon is a WinForm control, and requires a message loop, so why will declaring dummycontrol (or any WinForms control) set a SynchronizationContext, but the NotifyIcon does not?

推荐答案

这是您可以从参考源中发现的东西,同步提供程序由 WindowsFormsSynchronizationContext.InstallIfNeeded() 方法.查看引用以了解何时调用:

This is something you can discover from the Reference Source, the synchronization provider is installed by the WindowsFormsSynchronizationContext.InstallIfNeeded() method. Look at the references to see when it is called:

  • Application.Run()
  • Control 类构造函数
  • 分派 Begin/Invoke() 调用的辅助方法(不会发生).

NotifyIcon 派生自 Component,而不是 Control,因此永远不会命中这 3 个子弹中的任何一个.它是围绕 Shell_NotifyIcon() winapi 函数.我想你可以称它为错误,它的构造函数不调用 InstallIfNeeded() 但这有点牵强,你总是必须调用 Application.Run() 来使它起作用,这样你总是会遇到第一颗子弹.请注意初始化顺序.

NotifyIcon is derived from Component, not Control, so never hits one of those 3 bullets. It is a thin wrapper around the Shell_NotifyIcon() winapi function. I suppose you can call it bug that its constructor doesn't call InstallIfNeeded() but that's a bit of a stretch, you always must call Application.Run() to make it functional so you'll always hit the 1st bullet. Just beware initialization order.

这篇关于为什么 NotifyIcon 没有设置 SynchronizationContext?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 16:10