0

我正在尝试在线程一上创建一个MyReferenceTypeObject类型且值为 null 的变量,使用委托使该线程等于线程二上MyReferenceTypeObject的新实例,然后在线程一上访问MyReferenceTypeObject的成员(在委托回调方法)。

我的代码如下:

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。

4

1 回答 1

2

如果您想在长时间运行的操作期间保持 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

. Wait阻塞 GUI 线程。但是,您可以使用ContinueWithwhich 是异步的,因此是非阻塞的。此外,如果您想从异步方法中更新 UI,您还需要从 GUI 线程提供TaskScheduler( TaskScheduler.FromCurrentSynchronizationContext) 以防止跨线程异常。

于 2013-02-14T11:14:02.293 回答