我设计了一个异步套接字客户端,在连接之后我唤起了这个OnConnect例程。
目标是将主窗口中的状态文本设置为“已连接”,然后向用户显示登录对话框
Friend Sub OnConnect(ByVal ar As IAsyncResult)
Try
oSocket.EndConnect(ar)
MainDialog.SetStatus("Connected") <-- this line is giving the error
'We are connected so start listening for messages
byteData = New Byte(1023) {}
'Start listening to the data asynchronously
oSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceive), Nothing)
'// show login dialog
loginDlg = New LoginDialog
loginDlg.ShowDialog()
Catch ex As Exception
ShowMessage(String.Format(My.Resources.error_failed_reason, "connect", "server", ex.Message), MessageBoxIcon.Information)
End Try
End Sub
但我得到了一个例外
创建表单时出错。请参阅Exception.InnerException 细节。错误是:当前线程必须设置为单线程 在进行OLE调用之前的公寓(STA)模式。确保你的 主函数上标有STAThreadAttribute。
我没有使用任何线程,只是异步套接字
可能导致此错误的原因是什么? 是在另一个线程中调用的OnConnect吗?
修改
我刚刚添加了这个
我的应用程序单线程Public Class Program
<STAThread()> _
Shared Sub Main()
Dim frm As New MainDialog
Application.Run(frm)
End Sub
End Class
编辑2
我替换了这一行
MainDialog.SetStatus("Connected")
使用此行
If MainDialog.InvokeRequired Then <-- This line gives the same error as above
MainDialog.Invoke(New LoginDelegate(AddressOf ShowLogin), "Connected")
End If
我在上面的模块中创建了这个委托
Private Delegate Sub LoginDelegate(ByVal Item As Object)
答案 0 :(得分:2)
您不应更新工作线程中的UI。在工作线程中,MainDialog.SetStatus
和loginDlg.ShowDialog
都不是有效的事情。
理想情况下,您应该在UI线程中调用它。您可以致电Control.Invoke
或Control.BeginInvoke
来完成此操作。
答案 1 :(得分:0)
您需要使用STAThread
属性(阅读更多here)。请注意,您使用主线程 。如果您没有使用某个帖子,则无法运行您的程序。
答案 2 :(得分:0)
我能够自己解决我的问题,我所做的是将代码移动到MainDialog表单。
似乎maindialog.invoke无法从其他线程调用其他线程