我正试图在线程一上创建一个类型为MyReferenceTypeObject且值为null的变量,在线程二上使用委托使该线程等于MyReferenceTypeObject的新实例,然后在线程一(在委托回调方法中)访问MySReferenceTypeobject的成员。
我的代码如下:
Module Module1
Delegate Sub EditReferenceTypePropertyDelegate(ByVal referenceTypeObject As MyReferenceTypeObject, ByVal numberToChangeTo As Integer)
Sub Main()
Dim editReferenceDelegate = New EditReferenceTypePropertyDelegate(AddressOf EditReferenceTypeProperty)
Dim newReferenceTypeObject As MyReferenceTypeObject
editReferenceDelegate.BeginInvoke(newReferenceTypeObject, 2, AddressOf EditReferenceCallback, newReferenceTypeObject)
Console.ReadLine()
End Sub
Sub EditReferenceTypeProperty(ByVal referenceTypeObject As MyReferenceTypeObject, ByVal numberToChangeTo As Integer)
referenceTypeObject = New MyReferenceTypeObject()
referenceTypeObject.i = numberToChangeTo
End Sub
Sub EditReferenceCallback(ByVal e As IAsyncResult)
Dim referenceObject = DirectCast(e.AsyncState, MyReferenceTypeObject)
Console.WriteLine(referenceObject)
End Sub
End Module
Class MyReferenceTypeObject
Public Property i As Integer
End Class
但是,newReferenceTypeObject以null形式进入我的回调方法。我想我理解为什么,但问题是我需要从数据库中提取一些数据,然后将这些数据传递到newReferenceTypeObject的构造函数中,这需要几秒钟的时间,而且我不想在发生这种情况时锁定我的UI。我想在线程一上创建一个类型为MyReferenceTypeObject的字段,在线程二上实例化它(在我提取了数据库的数据以传递到构造函数之后),然后在实例化完成后在线程一中处理对象的成员。
这可能吗?我在Visual Studio 2012上使用VB.Net和.Net 4.0。
如果您想在长时间运行的操作中保持GUI的响应性,我会考虑使用Task<>
库(随.NET 4.0
一起提供)。下面是一个简单的例子。
Sub Main()
Dim instantiateTask = New Task(Of MyReferenceTypeObject)(Function()
' Call your database to pull the instantiation data.
Return New MyReferenceTypeObject With {.i = 2}
End Function)
instantiateTask.Start() ' Start the task -> invokes a ThreadPool.Thread to do the work.
instantiateTask.ContinueWith(Sub(x)
Console.WriteLine(x.Result.I)
End Sub, TaskScheduler.FromCurrentSynchronizationContext())
End Sub
CCD_ 3阻塞GUI线程。但是,您可以使用ContinueWith
,它是异步的,因此是非阻塞的。此外,您还需要从GUI线程提供TaskScheduler
(TaskScheduler.FromCurrentSynchronizationContex
t),以防止在您希望从异步方法中更新UI时出现跨线程异常。