我遇到'线程'问题。我希望有两个'形式'在单独的过程中工作,例如,如果我从一个'形式'打开'OpenFileDialog',另一个'形式'分开工作并做一些其他事情。 (看到我的代码,我的描述很糟糕。)
我使用'线程',它工作正常。但如果我的'form'具有'ContextMenuStrip'控件,则会发生错误'跨线程操作无效'。 请帮帮我。
感谢。
=============================================== ================================== FormMain:
Public Class FormMain
Private Sub cmdShow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdShow.Click
Form2.ShowMe()
End Sub
End Class
=============================================== ================================== 窗体2:
Public Class Form2
'Me.ContextMenuStrip1 = New System.Windows.Forms.ContextMenuStrip(Me.components)
'Me.Panel1 = New System.Windows.Forms.Panel
'Me.Panel1.ContextMenuStrip = Me.ContextMenuStrip1
Public Shared Thread_2 As System.Threading.Thread
Public MyDefaultWindowState = FormWindowState.Normal
Private Delegate Sub dlgShowMe()
Public Sub ShowMe()
If Thread_2 IsNot Nothing AndAlso Thread_2.ThreadState = Threading.ThreadState.Running Then
If Me.InvokeRequired Then
Dim d As New dlgShowMe(AddressOf Me.ShowMe)
Me.Invoke(d)
Else
Show_Activate_()
End If
Else
Thread_2 = New System.Threading.Thread(AddressOf Me.Show_View_)
Thread_2.SetApartmentState(System.Threading.ApartmentState.STA)
Thread_2.IsBackground = False
Thread_2.Start()
End If
End Sub
Private Sub Show_Activate_()
Try
Me.Enabled = True
Me.ShowInTaskbar = True
Me.WindowState = Me.MyDefaultWindowState
Me.BringToFront()
Me.Activate()
Catch ex As Exception
MsgBox(ex.Message, , "Show_Activate_")
End Try
End Sub
Private Delegate Sub dlgShow_View_()
Private Sub Show_View_()
Me.Enabled = True
Me.ShowInTaskbar = True
Try
Me.ShowDialog()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical,"Show_View_")
End Try
End Sub
Private Sub cmdOpenFileDialog1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOpenFileDialog1.Click
OpenFileDialog1.ShowDialog()
End Sub
End Class
=============================================== =
这是我的源代码: http://www.mediafire.com/?m8e8i51rr51a35i [63KB]
运行'FormMain'。 点击'cmdShow'。 当'Form2'显示时。右键单击“Panel1”。 将出现'ContextMenuStrip1'。
关闭'Form2。
再次点击“cmdShow”。 当'Form2'显示时。再次右键单击“Panel1”。 但你可以看到错误...
答案 0 :(得分:0)
错误是因为您尝试从不是UI线程(主线程)的线程修改GUI。
在更新UI或执行与UI相关的任何操作之前,您必须在任何控件上调用。
请考虑以下代码段:
Friend Shared Sub RaiseUiEvent(ByVal hnd As EventHandler, ByVal sender As Object, ByVal e As EventArgs)
Dim uiRef = GlobalManager.GetInstance().UI 'uiRef is just a ref to a control of my UI
uiRef.BeginInvoke(hnd, sender, e)
End Sub
BeginInvoke
是异步,Invoke
是同步
params是:一个将被执行的委托,最终是一个传递的对象数组。
但有些事情困扰着我,为什么你想让两个表单在不同的线程中“工作”?在任何情况下,你的GUI都不应该有任何繁重的处理。
编辑:
好的,所以我明白了什么是错的:你只需要一个非模态对话框! 但是OpenFileDialog是模态的(cf C# OpenFileDialog Non-Modal possible) 这个问题与线程无关!
答案 1 :(得分:0)
您未在此部分中调用
Private Delegate Sub dlgShow_View_()
Private Sub Show_View_()
Me.Enabled = True
Me.ShowInTaskbar = True
Try
Me.ShowDialog()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical,"Show_View_")
End Try
End Sub
你应该把它改成:
Private Delegate Sub dlgShow_View_()
Private Sub Show_View_()
if Me.InvokeRequired Then
Dim d as New dlgShow_View_(adressOf Show_View_)
else
Me.Enabled = True
Me.ShowInTaskbar = True
Try
Me.ShowDialog()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical,"Show_View_")
End Try
End If
End Sub