#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2004
    Location
    india
    Posts
    5
    Rep Power
    0

    database access using thread


    Hi,

    I am using visual basic 6.0 to create a std exe application. I am using Win32 API to create a background thread. The

    main user interface thread accesses an MS Access 2000 database using a connection string and places a record in the database

    table. Now the background thread accesses the same table using an ADODC object present on the main user interface and

    populates a text box on the main user interface form. The problem that i am facing is as follows.

    The background thread is able to read existing records and populates the text box txtService by using the data present in the

    text box txtServiceDB which is bound to the ADODC object ("service" field). But thee record newly inserted by the main user

    interface is not getting read.


    The code is as follows


    frmMain ( main user interface form)
    -------------------------------------------------------




    Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
    Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Private ThreadControl1 As MainApp

    Dim cnn As ADODB.Connection
    Dim strCnn As String
    Dim query As String



    Private Sub cmdCreate_Click()


    Dim mThreadPriority As ThreadPriority
    Dim mEnabled As Boolean

    mThreadPriority = tpNormal
    mEnabled = True
    ThreadControl1.CreateNewThread AddressOf threadRoutine, mThreadPriority, mEnabled

    End Sub

    Private Sub cmdInsertQuery_Click()


    strCnn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Program Files\Microsoft Visual Studio\VB98\FLS\FLS.mdb;Persist Security Info=False"
    Set cnn = New ADODB.Connection
    cnn.Open strCnn
    query = "INSERT INTO tblQueue ( service , type , prikey , field ) VALUES ( 'DPOPR' , 0 , '' , '' )"
    'MsgBox "Query is : " & query1
    cnn.Execute query, , adCmdText + adExecuteNoRecords
    cnn.Close

    End Sub

    Private Sub cmdTerminate_Click()
    ThreadControl1.TerminateCurrentThread
    End Sub

    Private Sub Form_Load()
    Set ThreadControl1 = New MainApp
    End Sub

    Private Sub Form_Unload(Cancel As Integer)
    'Terminate the Threads
    ThreadControl1.TerminateCurrentThread
    'Fully terminate the current process
    Call TerminateProcess(GetCurrentProcess, ByVal 0&)
    End Sub



    -------------------------------------------------------














    Module1 ( module)
    -------------------------------------------------------

    Private Declare Function timeGetTime Lib "winmm.dll" () As Long
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)




    Public Function threadRoutine()
    Dim i As Integer
    Dim calcArray(8) As String
    Dim PosBuf As Integer
    Dim TimeBuf As Long
    Do

    TimeBuf = timeGetTime
    Do While timeGetTime - TimeBuf < 5
    Sleep 5000
    Loop

    ' For i = 0 To 3
    ' 'calcArray(i) = _
    ' frmMain.DataGrid1.Columns(i).CellValue(frmMain.DataGrid1.Bookmark)
    ' Next i
    If Not frmMain.Adodc1.Recordset.EOF Then
    frmMain.Adodc1.Recordset.MoveNext
    frmMain.txtServiceDB.Refresh
    frmMain.txtService.Text = frmMain.txtServiceDB.Text
    Else
    frmMain.Adodc1.Recordset.MoveFirst
    End If
    TimeBuf = timeGetTime
    Do While timeGetTime - TimeBuf < 5
    Sleep 5000
    Loop


    Loop

    End Function


    -------------------------------------------------------










    MainApp (class module)
    -------------------------------------------------------


    'API Declarations
    'Creates a new thread
    Private Declare Function CreateThread Lib "kernel32" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
    'Terminates a thread
    Private Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
    'Sets the priority of a thread
    Private Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long
    'Returns the proirity of a thread
    Private Declare Function GetThreadPriority Lib "kernel32" (ByVal hThread As Long) As Long
    'Enables a disabled Thread
    Private Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long
    'Disables a thread
    Private Declare Function SuspendThread Lib "kernel32" (ByVal hThread As Long) As Long
    'Returns the handle of the current thread
    Private Declare Function GetCurrentThread Lib "kernel32" () As Long
    'Returns the ID of the current thread
    Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long

    'Consts
    Private Const MAXLONG = &H7FFFFFFF

    'Thread priority consts
    Private Const THREAD_BASE_PRIORITY_IDLE = -15
    Private Const THREAD_BASE_PRIORITY_LOWRT = 15
    Private Const THREAD_BASE_PRIORITY_MAX = 2
    Private Const THREAD_BASE_PRIORITY_MIN = -2
    Private Const THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX
    Private Const THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN
    Private Const THREAD_PRIORITY_ABOVE_NORMAL = (THREAD_PRIORITY_HIGHEST - 1)
    Private Const THREAD_PRIORITY_BELOW_NORMAL = (THREAD_PRIORITY_LOWEST + 1)
    Private Const THREAD_PRIORITY_ERROR_RETURN = (MAXLONG)
    Private Const THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE
    Private Const THREAD_PRIORITY_NORMAL = 0
    Private Const THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT

    'Thread creation flags
    Private Const CREATE_ALWAYS = 2
    Private Const CREATE_NEW = 1
    Private Const CREATE_NEW_CONSOLE = &H10
    Private Const CREATE_NEW_PROCESS_GROUP = &H200
    Private Const CREATE_NO_WINDOW = &H8000000
    Private Const CREATE_PROCESS_DEBUG_EVENT = 3
    Private Const CREATE_SUSPENDED = &H4
    Private Const CREATE_THREAD_DEBUG_EVENT = 2

    'Types and Enums
    Public Enum ThreadPriority
    tpLowest = THREAD_PRIORITY_LOWEST
    tpBelowNormal = THREAD_PRIORITY_BELOW_NORMAL
    tpNormal = THREAD_PRIORITY_NORMAL
    tpAboveNormal = THREAD_PRIORITY_ABOVE_NORMAL
    tpHighest = THREAD_PRIORITY_HIGHEST
    End Enum

    'Vars
    Private mThreadHandle As Long
    Private mThreadID As Long
    Private mPriority As Long
    Private mEnabled As Boolean
    Private mCreated As Boolean

    Public Function CreateNewThread(ByVal cFunction As Long, Optional ByVal cPriority As ThreadPriority = tpNormal, Optional ByVal cEnabled As Boolean = True)
    'Creates a new Thread
    Dim mHandle As Long
    Dim CreationFlags As Long
    Dim lpThreadID As Long

    'Look if the thread has already been created
    If mCreated = True Then Exit Function

    'Look if the thread should be enabled
    If cEnabled = True Then
    CreationFlags = 0
    Else
    'Create a disabled thread, can be enabled later with the
    ''Enabled' property
    CreationFlags = CREATE_SUSPENDED
    End If

    'The CreateThread Function returns the handle of the created thread;
    'if the handle is 0, it failed creating the thread
    mHandle = CreateThread(ByVal 0&, ByVal 0&, cFunction, ByVal 0&, CreationFlags, lpThreadID)

    If mHandle = 0 Then 'Failed creating the thread
    'Insert your own error handling
    'Debug.Print "InitializeThread Function in clsThreading failed creating a new thread"
    Else
    mThreadHandle = mHandle
    mThreadID = lpThreadID
    mCreated = True
    End If
    End Function

    Public Function TerminateCurrentThread()
    'Terminates the current thread

    'Ignore errors to prevent crashing if no thread has been created
    On Error Resume Next
    'Terminate the thread to prevent crashing if the app is closed
    'and the thread is still running (dangerous!)
    Call TerminateThread(mThreadHandle, ByVal 0&)
    mCreated = False
    End Function

    Public Property Get ThreadHandle() As Long
    'Returns the Handle of the current Thread
    ThreadHandle = mThreadHandle
    End Property

    Public Property Get ThreadID() As Long
    'Returns the ID of the current thread
    ThreadID = mThreadID
    End Property

    Public Property Get Priority() As Long
    'Returns a long value because the thread might have other priorities
    'than our five in the enum

    'Ignore errors to prevent crashing if no thread has been created
    On Error Resume Next
    Priority = GetThreadPriority(mThreadHandle)
    End Property

    Public Property Let Priority(ByVal tmpValue As ThreadPriority)
    'Sets the Thread Priority of the actual thread
    mPriority = tmpValue
    Call SetThreadPriority(mThreadHandle, tmpValue)
    End Property

    Public Property Get Enabled() As Boolean
    'Returns whether the Thread is enabled or not
    Enabled = mEnabled
    End Property

    Public Property Let Enabled(ByVal tmpValue As Boolean)
    'Enables/Disables the Thread

    'Ignore errors to prevent crashing if no thread has been created
    On Error Resume Next
    If tmpValue = True Then
    'Enable the thread
    Call ResumeThread(mThreadHandle)
    ElseIf tmpValue = False Then
    'Disable the thread
    Call SuspendThread(mThreadHandle)
    End If
    End Property

    Private Sub Class_Terminate()
    'Terminate the thread to prevent crashing if the app is closed
    'and the thread is still running (dangerous!)
    Call TerminateCurrentThread
    End Sub

    -------------------------------------------------------



    I was told that i could use win32 createmutex api to solve this problem. If so can anyone show me how could i implement the same for the code given



    database name : FLS.mdb
    table name : tblQueue
    table field : service -- type text
    type -- number
    prikey -- text
    field -- text

    Thanks in advance

    Regards,
    Clare
  2. #2
  3. No Profile Picture
    Banned
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2003
    Location
    UK
    Posts
    23
    Rep Power
    0
    Are you refreshing the data control after an entry has been made in the database?

    Nick
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2004
    Location
    Sweden
    Posts
    271
    Rep Power
    0
    I don't quite understand your code, specilly the sleep. Why do you want your app to sleep. But I don't think it sleeps very much.

    I would suggest you use API CreateEvent to trigger the API WaitForSingleObject in your thread. The event is when you insert an item in the database.

    You can read about CreateMutex

    Why don't you set text in the editbox at the same time as you insert the item and skip the background thread.
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Posts
    2
    Rep Power
    0
    Threads in vb is a major pain and I would avoid it at all costs. Get .net if you need threads, you will save a lot of agony, time and money. I'm surprised your post didn't start with "I am having trouble with a GPF...", since VB is not very thread safe...

    Why do you need a thread to populate a list box after adding a record to a database? Is it some big long time consuming calculation?

IMN logo majestic logo threadwatch logo seochat tools logo