【问题标题】:"Value can not be null" on singleton instantiation单例实例化时的“值不能为空”
【发布时间】:2013-08-26 14:26:07
【问题描述】:

我有一个我试图实例化的单例类,它给出了异常“值不能为空”

我在我的主要形式中声明了一个引用,例如:

Dim devices As DeviceUnderTestBindingList

然后在我的 form.load 中实例化:

devices = DeviceUnderTestBindingList.GetInstance

DeviceunderTestBindingList 类如下:

Imports System.ComponentModel

Public Class DeviceUnderTestBindingList
    ' DeviceUnderTest is one of my other regular classes...
    Inherits System.ComponentModel.BindingList(Of DeviceUnderTest)

    Private Shared SingleInstance As DeviceUnderTestBindingList
    Private Shared InstanceLock As Object
    Private Shared ListLock As Object

    Private Sub New()
        MyBase.New()
    End Sub

    Public Shared ReadOnly Property GetInstance As DeviceUnderTestBindingList
        Get
            ' Ensures only one instance of this list is created.
            If SingleInstance Is Nothing Then
                SyncLock (InstanceLock)
                    If SingleInstance Is Nothing Then
                        SingleInstance = New DeviceUnderTestBindingList
                    End If
                End SyncLock
            End If
            Return SingleInstance
        End Get
    End Property
End Class

我之前用过同样的模式没有问题,现在突然出现异常,但是为什么呢?

请注意:这是一个 VB.NET Q!我已经阅读了很多处理类似问题的 C# Q,但对它们的理解还不够。

【问题讨论】:

  • 哪一行出现错误?是运行时异常还是编译时错误?
  • 正如我所提到的,当我尝试实例化它时,即在devices = DeviceUnderTestBindingList.GetInstance 行,并在我运行程序时发生(虽然在 form.load 事件中,所以只有在我在这条线上放了一个 Try...catch)
  • 您能否在问题中包含异常的堆栈跟踪?我怀疑这将有助于解决问题。
  • @StevenDoggart,我实际上不知道在哪里可以找到堆栈跟踪,但我想我已经将它缩小到SyncLock(InstanceLock) 行。如果我摆脱它们并且额外检查什么都没有,那么它就可以工作......
  • 我怀疑这可能是问题所在......

标签: vb.net exception singleton


【解决方案1】:

问题是你不能SyncLock 在一个空变量上。您只能在对象的有效实例上使用SyncLock。您需要更改此行:

Private Shared InstanceLock As Object

到这里:

Private Shared InstanceLock As New Object()

【讨论】:

  • 太棒了!这么小事就让人沮丧!
【解决方案2】:

只是想补充一点,这个问题让我回头看看单例模式,我终于明白了如何使用 Lazy(T) 模式,尽管我仍然不确定它的线程安全性如何。这是VB代码:

Public Class MyClass
    Private Shared SingleInstance As Lazy(Of MyClass) = New Lazy(Of MyClass)(Function() New MyClass())

    Private sub New ()
        MyBase.New()
    End Sub

    Public Shared ReadOnly Property GetInstance
        Get
            Return SingleInstance.value
        End Get
    End Property
End Class

然后像在我的 OP 中一样声明和实例化。 (这仅适用于 .NET 4 及更高版本)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    相关资源
    最近更新 更多