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 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?
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()
- The Control class constructor
- The helper method that dispatches Begin/Invoke() calls (won't happen).
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.