通过BackgroundWorker启动的线程无法看到My.Application.myObject的值

时间:2013-09-20 22:26:17

标签: .net vb.net

我正在扩展一个.NET 3.5应用程序,其中包含其他人奠定的基础,并且成员变量已添加到名称空间My中:

Namespace My
    Private connection As SqlClient.SqlConnection
    Friend appSession As SomeCustomNamespace.clsSession
    ' and a few more others...
End Namepace

我有一些形式并在那里进行处理。如果我以标准方式运行代码(OnClick ...),两个成员变量都有它们的值。如果我将相同的代码移至BackgroundWorker并通过RunWorkerAsync()启动,则第一个变量具有值,但第二个变量为Nothing(null)。

导致问题的原因是什么?如何纠正或解决这个问题? (My.Application.appSession必须设置,因为许多方法都引用它。)

(是否有机会在使用全局变量实现的应用程序中使用后台工作程序作业?)

1 个答案:

答案 0 :(得分:0)

经过一番研究后,我决定将My.Application作为参数传递给BackgroundWorker.Run(),并在BackgroundWorker_DoWork()中将接收参数的浅表副本传回My.Application。因此我得到了My.Application的内容。

Private Sub StartBackgroundWork() 
    Me.BackgroundWorker.RunWorkerAsync(My.Application)
End Sub

Private Sub BackgroundWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) _
        Handles BackgroundWorker.DoWork

    My.Application.ShallowCopyFrom(e.Argument)

    'start work here...
End Sub
我基于this StackOverflow answer创建的

ShallowCopyFrom()方法。在VB中,必须将其放入代码 module (使用添加模块... 命令,而不是添加类... ):

Imports System.Reflection

Module CompilerExtensionsModule

<System.Runtime.CompilerServices.Extension> _
<System.ComponentModel.Description("Performs shallow copy of fields of given object into this object based on mathing field names.")> _
Public Sub ShallowCopyFrom(Of T1 As Class, T2 As Class)(ByRef obj As T1, ByRef otherObject As T2)
    Dim srcProps As Reflection.PropertyInfo() =
        otherObject.[GetType]().GetProperties(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.[Public] Or Reflection.BindingFlags.GetProperty)

    Dim destProps As Reflection.PropertyInfo() =
        obj.[GetType]().GetProperties(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.[Public] Or Reflection.BindingFlags.SetProperty)

    For Each [property] As Reflection.PropertyInfo In srcProps
        Dim dest = destProps.FirstOrDefault(Function(x) x.Name = [property].Name)
        If Not (dest Is Nothing) AndAlso dest.CanWrite Then
            dest.SetValue(obj, [property].GetValue(otherObject, Nothing), Nothing)
        End If
    Next

    Dim srcFields As Reflection.FieldInfo() =
        otherObject.[GetType]().GetFields(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Public)

    Dim destFields As Reflection.FieldInfo() =
        obj.[GetType]().GetFields(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Public)

    For Each [field] As Reflection.FieldInfo In srcFields
        Dim dest = destFields.FirstOrDefault(Function(x) x.Name = [field].Name)
        If Not (dest Is Nothing) Then
            dest.SetValue(obj, [field].GetValue(otherObject))
        End If
    Next

End Sub

End Module