Results 1 to 9 of 9

Thread: Threading problem

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    526

    Exclamation Threading problem

    Hi Guys,

    I am using VB.NET (2008). I have tried using threading before and I did encounter issues. Then I wrote in this forum and jmcilhinney helped me. It did solve my problem and I am grateful for that. The thread can be found here
    Thread here

    My current problem is as follows :-

    - I have a form with various controls incl a timer control.
    - Task: when i click on start , timer starts and at regular intervals it downloads a file and processes it.
    - Then it becomes idle for a while before repeating it.
    - No threading used in this form so far.

    Now when the timer is idle then I need to do some processing. So I thought that I can create a thread and use that thread to do the processing so that the application remains responsive.

    I wrote the following code :

    Code:
    ' General
    Dim DataThread as Thread
    
    Private Sub TimerMain_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TimerMain.Tick
    
    If timerjobdone = True then
    Call ExecuteThreadCode()
    TimerMain.Interval = 10000
    end if
    
    End Sub
    
    Private Sub ExecuteThreadCode()
    
    DataThread = new thread(addressof DoProcessing)
    Datathread.start
    
    
    End Sub
    
    Private sub DoProcessing()
    
    ' Here I need to access the label of the form so i need to do invoke method
    ' I do some file reading and other processing here
    
    End sub
    Now when the code segment executes my application becomes unresponsive. I mean i used threading to make program more accessible to user or responsive but it does not work.

    Will be glad if anyone can help me out.

    Thanks a lot,

    GR

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Threading problem

    You don't actually need the ExecuteThreadCode method, as you could move what is inside of it into the timer. It doesn't hurt, though, if you find it cleaner this way.

    I would say that the issue lies in the part that you didn't post: The thread method itself.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    526

    Re: Threading problem

    The code inside the thread method is bit long and complex. It's basically opening files, processing them and downloading some small files and processing them.

    What I wanted to know is why it is not working like an independant thread? why does my program become unresponsive.

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Threading problem

    You also mentioned interacting with form controls from the background thread. Perhaps that was done in a way that blocks the UI. The code you have shown doesn't have any obvious issues in it. However, you can put a breakpoint on the first line in the timer event, and step through it. If it is blocking somewhere, you will see it. If it isn't, and the timer event code finishes up normally, then it is the background thread itself that is blocking the UI thread. Without seeing the code, nobody can answer that definitively. However, if there is lots of code...perhaps nobody can answer definitively anyhow.

    The first thing I would do would be to step through the timer event. That shouldn't cause a problem as you have it now, so the next thing I would do would be to take a look at any interactions between the thread and the UI.
    My usual boring signature: Nothing

  5. #5
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Threading problem

    Wouldn't this be a good time to put some Debug.Writeline statements into the main code, the timer events and the thread methods?

    Won't all these Debug.Writeline's appear in the OUTPUT window telling you exactly where the flow of the code is going?

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    526

    Question Re: Threading problem

    The code for the sub that does the processing (which I didnt write before) is :

    Code:
    Private Sub DoProcessing()
     If Me.InvokeRequired = True Then
                Me.lblstatus.Invoke(New MethodInvoker(AddressOf DoProcessing))
            Else
                Try
                    ' this function will check for data. 
    
                    ' CHECKS/Validation
                    If Now.DayOfWeek = DayOfWeek.Saturday Then Exit Sub
    
                    Dim FPath As String = DataPath & "\Abc.txt"
                    If File.Exists(FPath) = False Then Exit Sub
    
                    Dim CTime As DateTime = Now, GoAhead As Boolean = False, Cnt As Integer = 0
    
                    If Format$(CTime, "HHmm").ToString.Substring(3, 1) = "5" Or Format$(CTime, "HHmm").ToString.Substring(3, 1) = "0" Then
                        GoAhead = True  ' means we have 5 min in hand and we can go ahead and check
                    Else
                        Do
                            Cnt = Cnt + 1
                            CTime = CTime.AddMinutes(1)
                            If Format$(CTime, "HHmm").ToString.Substring(3, 1) = "5" Or Format$(CTime, "HHmm").ToString.Substring(3, 1) = "0" Then Exit Do
                            If Cnt > 5 Then Exit Do ' EMERGENCY EXIT
                        Loop
                        If Cnt >= 3 Then GoAhead = True Else GoAhead = False
                    End If
    
                    If GoAhead = False Then Exit Sub
    
                    ' Checks Done
                    Dim FileData() As String = File.ReadAllLines(FPath), FTemp() As String
                    Dim FileTime As DateTime, FileDate As Date, Ticks() As String, EndTime As DateTime
                    Dim RecCount As Long = 0, ReadCounter As Long = 0
    
                    ReDim Ticks(0)
    
                    If UBound(FileData) < 3 Then
                        Exit Sub ' get out
                    End If
    
                   lblstatus.Text = "Status: Checking for data..." : lblstatus.Refresh()
    
                    For i As Long = UBound(FileData) To LBound(FileData) Step -1
                        If FileData(i).Trim = "" Then Continue For
                        ReadCounter += 1
                        FileDate = New Date(FileData(i).ToString.Substring(6, 4), FileData(i).ToString.Substring(3, 2), FileData(i).ToString.Substring(0, 2))
                        RecCount = i
    
                        If ReadCounter = 1 Then ' Get End Time
                            FTemp = FileData(i).Split(",")
                            EndTime = New DateTime(Now.Date.Year, Now.Date.Month, Now.Date.Day, FTemp(1).Substring(0, 2), FTemp(1).Substring(2, 2), 0)
                        End If
    
                        If Format$(FileDate, "yyyyMMdd") <> Format$(Now.Date, "yyyyMMdd") Then
                            Exit For
                        End If
                    Next
    
                    If RecCount = UBound(FileData) Then
                        ' no rec found display message and get out
                        lblstatus.Text = "Status: Data check completed"  lblstatus.Refresh()
                        Exit Sub
                    End If
    
                    ReadCounter = 0 : RecCount += 1
                    FileTime = New DateTime(Now.Date.Year, Now.Date.Month, Now.Date.Day, "09", "05", "0")
    
                    Do
                        ReadCounter = ReadCounter + 1
                        If RecExistsInArray(FileData, RecCount, Format$(FileTime, "HHmm")) = True Then
                            FileTime = FileTime.AddMinutes(5)
                        Else
                            ReDim Preserve Ticks(UBound(Ticks) + 1)
                            Ticks(UBound(Ticks)) = Format$(FileTime, "HHmm")
                            FileTime = FileTime.AddMinutes(5)
                        End If
                        If FileTime = EndTime Then Exit Do
                        If ReadCounter > 70 Then Exit Do ' Emergency Exit
                    Loop
    
                    ' NOW DOWNLOAD THOSE Files
                    Dim DownloadedTicks() As String : ReDim DownloadedTicks(0)
    
                    For i As Integer = 1 To UBound(Ticks)
                        Try
                            If File.Exists(Application.StartupPath & "\" & Ticks(i) & ".dat") = True Then File.Delete(Application.StartupPath & "\" & Ticks(i) & ".dat")
                            My.Computer.Network.DownloadFile("www.mysite.com/" & Format(DateTimePicker1.Value.Date, "ddMMyy") & "/" & Ticks(i) & ".dat", Application.StartupPath & "\" & Ticks(i) & ".dat")
                            ReDim Preserve DownloadedTicks(UBound(DownloadedTicks) + 1) ' tick downloaded
                            DownloadedTicks(UBound(DownloadedTicks)) = Ticks(i)
                        Catch ex As Exception
                            ' means couldnt download or find file
                        End Try
                    Next
    
                    If UBound(DownloadedTicks) = 0 Then
                        ' didnt find file so quit/exit
                        lblstatus.Text = "Status: Data check completed" : lblstatus.Refresh()
                        Exit Sub
                    End If
    
                    ' Found some/all missed ticks
                    ' Read them
    
                    ' File Reading routine not pasted right now
    
    
                   lblstatus.Text = "Status: Data updated successfully " 
    
                Catch ex As Exception
                    Threading.Thread.Sleep(1500)
                End Try
            End If       ' Endif for Me.Invoke Required
    End Sub
    Now inspite of executing the above code in thread, the application locks up till processing does not finish. Why? Do i need to use doevents or I dunno why? I did use debug to check the flow and found no problems in the flow.

    Please help me here.
    Thank you.

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Threading problem

    The problem is that you're NOT executing that code in a separate thread. You start a new thread and call DoProcessing, then the very first thing that DoProcessing does is invoke a call back to the UI thread and ALL the work is done there.

    You are supposed to do all your work on the worker thread and then invoke a call back to the UI thread ONLY to access the UI. Get rid of any that If block and any interaction with the UI from that method. Then that whole method will be executed on the worker thread. You then write a new method ONLY for interaction with the UI, e.g.
    vb.net Code:
    1. Private Sub UpdateLabel(ByVal text As String)
    2.     If Me.lblstatus.InvokeRequired Then
    3.         Me.lblstatus.Invoke(New MethodInvoker(AddressOf DoProcessing), text)
    4.     Else
    5.         Me.lblstatus.Text = text
    6.     End If
    7. End Sub
    You can then call that method from DoProcessing to update lblstatus.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    526

    Unhappy Re: Threading problem

    Quote Originally Posted by jmcilhinney View Post
    The problem is that you're NOT executing that code in a separate thread. You start a new thread and call DoProcessing, then the very first thing that DoProcessing does is invoke a call back to the UI thread and ALL the work is done there.

    You are supposed to do all your work on the worker thread and then invoke a call back to the UI thread ONLY to access the UI. Get rid of any that If block and any interaction with the UI from that method. Then that whole method will be executed on the worker thread. You then write a new method ONLY for interaction with the UI, e.g.
    vb.net Code:
    1. Private Sub UpdateLabel(ByVal text As String)
    2.     If Me.lblstatus.InvokeRequired Then
    3.         Me.lblstatus.Invoke(New MethodInvoker(AddressOf DoProcessing), text)
    4.     Else
    5.         Me.lblstatus.Text = text
    6.     End If
    7. End Sub
    You can then call that method from DoProcessing to update lblstatus.
    Thanks buddy for your help. I removed the invoke call to UI thread statements. The DoProcessing sub now does not directly access the UI.
    But still the application behaves like before that is it locks up till the processing isn't over. I am unable to understand why?.

    Code:
     Private Sub DoProcessing()
            Try
                ' this function will check for data. 
                ' CHECKS/Validation
    
                If ProgramSettings.CheckForMissedData = False Then Exit Sub
                If Now.DayOfWeek = DayOfWeek.Saturday Then Exit Sub
    
                Dim FPath As String = DataPath & "\Abc.txt"
                If File.Exists(FPath) = False Then Exit Sub
    
                Dim CTime As DateTime = Now, GoAhead As Boolean = False, Cnt As Integer = 0
    
                If Format$(CTime, "HHmm").ToString.Substring(3, 1) = "5" Or Format$(CTime, "HHmm").ToString.Substring(3, 1) = "0" Then
                    GoAhead = True  ' means we have 5 min in hand and we can go ahead and check
                Else
                    Do
                        Cnt = Cnt + 1
                        CTime = CTime.AddMinutes(1)
                        If Format$(CTime, "HHmm").ToString.Substring(3, 1) = "5" Or Format$(CTime, "HHmm").ToString.Substring(3, 1) = "0" Then Exit Do
                        If Cnt > 5 Then Exit Do ' EMERGENCY EXIT
                    Loop
                    If Cnt >= 3 Then GoAhead = True Else GoAhead = False
                End If
    
                If GoAhead = False Then Exit Sub
    
                ' Checks Done
                Dim FileData() As String = File.ReadAllLines(FPath), FTemp() As String
                Dim FileTime As DateTime, FileDate As Date, Ticks() As String, EndTime As DateTime
                Dim RecCount As Long = 0, ReadCounter As Long = 0
    
                ReDim Ticks(0)
    
                If UBound(FileData) < 3 Then
                    Exit Sub ' get out
                End If
    
                Call LabelReset("Status: Checking for missed data")
    
                For i As Long = UBound(FileData) To LBound(FileData) Step -1
                    If FileData(i).Trim = "" Then Continue For
                    ReadCounter += 1
                    FileDate = New Date(FileData(i).ToString.Substring(6, 4), FileData(i).ToString.Substring(3, 2), FileData(i).ToString.Substring(0, 2))
                    RecCount = i
    
                    If ReadCounter = 1 Then ' Get End Time
                        FTemp = FileData(i).Split(",")
                        EndTime = New DateTime(Now.Date.Year, Now.Date.Month, Now.Date.Day, FTemp(1).Substring(0, 2), FTemp(1).Substring(2, 2), 0)
                    End If
    
                    If Format$(FileDate, "yyyyMMdd") <> Format$(Now.Date, "yyyyMMdd") Then
                        Exit For
                    End If
                Next
    
                If RecCount = UBound(FileData) Then
                    Exit Sub
                End If
    
                ReadCounter = 0 : RecCount += 1
                FileTime = New DateTime(Now.Date.Year, Now.Date.Month, Now.Date.Day, "09", "05", "0")
    
                Do
                    ReadCounter = ReadCounter + 1
                    If RecExistsInArray(FileData, RecCount, Format$(FileTime, "HHmm")) = True Then
                        FileTime = FileTime.AddMinutes(5)
                    Else
                        ReDim Preserve Ticks(UBound(Ticks) + 1)
                        Ticks(UBound(Ticks)) = Format$(FileTime, "HHmm")
                        FileTime = FileTime.AddMinutes(5)
                    End If
                    If FileTime = EndTime Then Exit Do
                    If ReadCounter > 70 Then Exit Do ' Emergency Exit
                Loop
    
                ' Done now check if there were missed ticks or not
                If UBound(Ticks) = 0 Then
                    ' All ticks present so far 
                    Call LabelReset("Status: No ticks missed so far")
                    Exit Sub
                End If
    
                ' NOW DOWNLOAD THOSE TICKS
                Dim DownloadedTicks() As String : ReDim DownloadedTicks(0)
    
                For i As Integer = 1 To UBound(Ticks)
                    Try
                        If File.Exists(Application.StartupPath & "\" & Ticks(i) & ".dat") = True Then File.Delete(Application.StartupPath & "\" & Ticks(i) & ".dat")
                        My.Computer.Network.DownloadFile("http://www.mysite.com/" & Format(DateTimePicker1.Value.Date, "ddMMyy") & "/" & Ticks(i) & ".dat", Application.StartupPath & "\" & Ticks(i) & ".dat")
                        ReDim Preserve DownloadedTicks(UBound(DownloadedTicks) + 1) ' tick downloaded
                        DownloadedTicks(UBound(DownloadedTicks)) = Ticks(i)
                    Catch ex As Exception
                        ' means couldnt download or find file
                    End Try
                Next
    
                If UBound(DownloadedTicks) = 0 Then
                    ' didnt find file so quit/exit
                    '    lblstatus.Text = "Status: Missed data check completed" : lblstatus.Refresh()
                    ' commented above
                    Exit Sub
                End If
    
                ' Found some/all ticks
                ' Read data files in array
                ' Code for Processing File Not Pasted
            
                Call LabelReset("Status: DONE")
            Catch ex As Exception
                
            End Try
    
        End Sub
    
     Private Sub LabelReset(ByVal text As String)
            If Me.InvokeRequired = True Then
                Me.lblstatus.Invoke(New MethodInvoker(AddressOf DoProcessing), text)
            Else
                lblstatus.Text = text : lblstatus.Refresh()
            End If
        End Sub
    
    ' Timer code
    
     Private Sub TimerMain_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TimerMain.Tick
        
       If LastCheckOK() = True Then
                lblstatus.Text = "Status: Waiting for next data" : lblstatus.Refresh()
                TimerMain.Interval = GetTimerInterval()
               ' calling thread
                MissedTickThread = New Thread(AddressOf DoProcessing)
                MissedTickThread.Start()
                Exit Sub
            End If
    
    End Sub
    Cheers.
    Last edited by greatchap; Jan 13th, 2010 at 07:12 AM.

  9. #9

    Thread Starter
    Fanatic Member
    Join Date
    Feb 2004
    Location
    India
    Posts
    526

    Re: Threading problem

    I tried using background worker control but it didnt work the way I wanted. My app still locks up until processing is completed. Kinda strange isn't it ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width