我有一個Windows窗體應用程序,它使用Shared類來容納應用程序的所有公共對象。 settings類擁有一組定期處理事物的對象,然後有一些有趣的事情,他們需要提醒主窗體並更新它。強制多線程VB.NET類在單個窗體上顯示結果
我目前正在通過對象上的事件來完成此任務,並且在創建每個對象時,我添加一個EventHandler以將事件映射回窗體。但是,我遇到了一些麻煩,表明這些請求並不總是以我的表單的主要副本結尾。例如,我的表單有一個通知托盤圖標,但是當表單捕捉並顯示事件並嘗試顯示氣泡時,不會出現氣泡。但是,如果我修改該代碼以使圖標可見(儘管它已經存在),然後顯示氣泡,則會出現第二個圖標並正確顯示氣泡。
有沒有人碰到過這個?有沒有一種方法可以強制我的所有事件被表單的單個實例捕獲,還是有一種完全不同的方式來處理?如有必要,我可以發佈代碼示例,但我認爲這是一個常見的線程問題。
更多信息:我目前在窗體上的事件處理程序中使用Me.InvokeRequired,並且在這種情況下總是返回FALSE。另外,當我通過這個表單顯示時創建的第二個托盤圖標上沒有上下文菜單,而「真實」圖標卻沒有 - 這是否會影響任何人?
我要把我的頭髮拉出來!這不可能是那麼難!
解決方案:感謝nobugz提供的線索,它將我引向我正在使用的代碼(雖然我不禁想着有更好的方法來做到這一點,但我現在正在使用該代碼)。我添加了一個私有的布爾變量叫「值isPrimary」的形式,並添加以下代碼添加到窗體構造函數:
Public Sub New()
If My.Application.OpenForms(0).Equals(Me) Then
Me.IsFirstForm = True
End If
End Sub
一旦這個變量被設置和構造完成,它朝向正確的事件處理程序,我以這種方式處理它(CAVEAT:由於我正在尋找的表單是應用程序的主要形式,My.Application.OpenForms(0)得到我所需要的。如果我正在尋找非易失性存儲器的第一個實例,啓動窗體,我不得不遍歷,直到我找到它):
Public Sub EventHandler()
If Not IsFirstForm Then
Dim f As Form1 = My.Application.OpenForms(0)
f.EventHandler()
Me.Close()
ElseIf InvokeRequired Then
Me.Invoke(New HandlerDelegate(AddressOf EventHandler))
Else
' Do your event handling code '
End If
End Sub
首先,它會檢查它是否正確的表格上運行 - 如果不是,則調用右擊形式。然後檢查線程是否正確,如果不是,則調用UI線程。然後它運行事件代碼。我不喜歡這可能是三個電話,但我想不出另一種方式來做到這一點。它似乎工作得很好,雖然它有點麻煩。如果有人有更好的方法來做到這一點,我很樂意聽到它!
再一次,感謝所有的幫助 - 這會讓我瘋狂!
作爲回報,我已經更新了我的問題與我想出了根據您的線索的解決方案。感謝您的轉向! – SqlRyan 2008-11-10 15:34:15