你需要有UI线程调用frmMain.refreshStats方法。使用Control.InvokeRequired属性和Control.Invoke(MSDN Documentation)这样做当然有许多方法。
你可以有“EndAsync”的方法使该方法调用UI线程安全的,或有(使用Control.InvokeRequired)线程安全的refreshStats方法检查。
EndAsync UI线程安全的将是这样的:
Public Delegate Sub Method(Of T1, T2)(ByVal arg1 As T1, ByVal arg2 As T2)
Sub skDataReceived(ByVal result As IAsyncResult)
Dim frmMain As Form = CType(My.Application.OpenForms.Item("frmMain"), frmMain)
Dim d As Method(Of Object, Object)
'create a generic delegate pointing to the refreshStats method
d = New Method(Of Object, Object)(AddressOf frmMain.refreshStats)
'invoke the delegate under the UI thread
frmMain.Invoke(d, New Object() {d1, d2})
End Sub
或者你可以有refreshStats方法检查,看是否需要调用自身的UI线程下:
Public Delegate Sub Method(Of T1, T2)(ByVal arg1 As T1, ByVal arg2 As T2)
Sub refreshStats(ByVal d1 As Object, ByVal d2 As Object)
'check to see if current thread is the UI thread
If (Me.InvokeRequired = True) Then
Dim d As Method(Of Object, Object)
'create a delegate pointing to itself
d = New Method(Of Object, Object)(AddressOf Me.refreshStats)
'then invoke itself under the UI thread
Me.Invoke(d, New Object() {d1, d2})
Else
'actual code that requires UI thread safety goes here
End If
End Sub
如果我直接调用frmMain,我得到一个错误,指出调用只能在窗口句柄创建后在控件上调用。所以我试图在OpenForms集合中使用表单,但是我得到了同样的旧错误:“撤消操作...”我做错了什么? – 2009-11-15 06:48:03
换句话说,你的“解决方案”不*解决我的基本问题,即InvalidContextException。无论如何,如果有人再次遇到这个问题,我已经找到了答案。请参阅下面的答案。 – 2009-11-15 07:46:02
所以基本上我认为是在Windows为窗体窗口创建Win32句柄之前执行此代码。我很好奇,是代码运行之前显示的窗口? – 2009-11-15 20:33:11