ProgrammingBackend Developer (VB.NET)

How is the Singleton design pattern implemented in Visual Basic, what should be considered for thread safety, and what is the difference between the classic and lazy (lazy) implementation?

Pass interviews with Hintsage AI assistant

Answer.

The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. In VB.NET, a private constructor and a static property are commonly used to hold the single instance:

Public Class Singleton Private Shared _instance As Singleton Private Sub New() ' Private constructor End Sub Public Shared ReadOnly Property Instance() As Singleton Get If _instance Is Nothing Then _instance = New Singleton() End If Return _instance End Get End Property End Class

Thread Safety: In a multithreaded environment, it is possible to create two instances when accessed simultaneously. Solution: use locking or the Lazy(Of T) construct:

' Lazy thread-safe implementation Public Class Singleton Private Shared ReadOnly _instance As New Lazy(Of Singleton)(Function() New Singleton()) Private Sub New() End Sub Public Shared ReadOnly Property Instance() As Singleton Get Return _instance.Value End Get End Property End Class

Difference:

  • The classic Singleton creates an instance at the first access but requires manual synchronization.
  • The "lazy" variant uses built-in .NET mechanisms to create the instance in a thread-safe manner.

Trick Question.

What is dangerous about such a code for implementing Singleton?

Public Shared ReadOnly Property Instance() As Singleton Get If _instance Is Nothing Then _instance = New Singleton() End If Return _instance End Get End Property

Answer: In a multithreaded environment, there may be a situation where two threads simultaneously see that _instance is Nothing and both create an object. Therefore, this approach is not completely thread-safe. It is recommended to use Lazy(Of T) or SyncLock for locking.

Examples of real errors due to ignorance of the subtleties of the topic.


Story

ERP system: Singleton logger sometimes created twice when started from services, losing logs. The reason was the lack of synchronization in the property, even though the application was multithreaded.


Story

Windows Forms application: In the project, database work was extracted into a Singleton, but lazy initialization was not implemented. Upon application startup, a heavy connection occurred, slowing down UI loading for everyone.


Story

Plugin for a journalistic platform: Tried to use a static variable in a module for Singleton, which was not protected from multithreaded access; as a result, several instances of the email distribution handler appeared during peak load, causing duplicate emails.