views:

40

answers:

1

Hello all. I'm a newbie to threading, trying to learn it as I go. Please don't make any assumptions and try to explain threading concepts and rules that might seem obvious.

I have a Module (Static class) as follows:

Module Main

Private ReadOnly _dbConn As SqlClient.SqlConnection

Public ReadOnly Property DBConn() As SqlClient.SqlConnection
    Get
        Debug.Print("Accessing DBConn")
        Return _dbConn
    End Get
End Property

Sub New()
    _dbConn = New SqlClient.SqlConnection(My.Resources.ConnectionString)
End Sub

End Module

All throughout the application, when i access DBConn on the same thread, it works as expected. howeve, later on I created a background worker that tries to access DBConn and nothing happens, the thread just hanges (the Background worker). I dont get the printout and the application doesnt continue. the background worker thread doesnt continue past that point, and so the thread never exits. I dont get any exceptions, and i Cant debug in Visual Studio (visual studio hangs). I guess its a 2 part question: why cant i access DBConn from the other thread, and why does it hang without giving me a threadAccess exception? also, why does visual studio hang (I'm assuming it hanges because the thread is hanging)?

Please Note: I am not asking about practice. I know I shouldnt be sharing the same connection, rather returning a new connection. in this particular application it is safe since (although i execute it on a background thread) as per the flow of the application, the connection can only be accessed one at a time. I just want to know why it hangs accross the thread.

A: 

This should be a class not a module. Then you can use a reference to pass the connection to the appropriate thread.

For example:

Private myConn as New NameofDataConnectionClass
Private myWorkerClass as New NameofProcessClass
myWorkerClass.DataConnection = myConn
Private thd as New Threading.Thread(AddressOf myWorkerClass.Method)
thd.Start()

Obviously, that is coded logically not specifically. The point is to instantiate your connection class and then pass it to the appropriate class that is being handled by the thread or background worker.

Josaph
A Module is an instaniated class. In VB, when writing a constructor in a module, it is a static constructor that gets intialized as soon as any referece is made to any member in the module. by the time I call the connection, it has already been instantiated by the static constructor. This is supported by the fact that the connection Member is accessed before it is being called by the other thread. I am not recieving a NullRefererenceException. Please explaing in detail what the problem is and what your solution is.
Fragilerus
When you use cross thread, you need to pass the reference of the object because the instantiated module doesn't pass to the new thread. It remains in the current thread of your application. That is why you need to pass an object reference to the new thread of the class wrapping your data connection.
Josaph
I dont think that is correct. Threads share the Heap memory space. Therefore the other thread should be able to access the same instance of the module. I tested this and it preformed as expected Private Sub Temp() Dim bg As New System.ComponentModel.BackgroundWorker AddHandler bg.DoWork, AddressOf Change bg.RunWorkerAsync() Threading.Thread.Sleep(TimeSpan.FromSeconds(3)) Console.WriteLine(Module1.Member) End Sub Public Sub (ByVal sender As Object, ByVal e As DoWorkEventArgs) Module1.Member = "Changed" End Sub
Fragilerus