1. Welcome to TechPowerUp Forums, Guest! Please check out our forum guidelines for info related to our community.

Visual basic text file nightmare

Discussion in 'Programming & Webmastering' started by shuggans, Mar 28, 2011.

  1. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,817 (3.59/day)
    Thanks Received:
    5,629
    Location:
    Cheeseland (Wisconsin, USA)
    @shuggans,
    Sorry for going off-topic. lol
    It looks like you are starting a thread but still running the loop in your main method.
     
    shuggans says thanks.
    10 Year Member at TPU
  2. CrackerJack

    Joined:
    Dec 13, 2007
    Messages:
    2,758 (0.78/day)
    Thanks Received:
    470
    Still can't figure it out, But you have the thread start wrong....

    Code:
    Imports System.IO
    Imports System.Threading
    
    Public Class Form1
    
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    'Thread start should be here, other wise it's repeat it self over and over till stop
    readlog() 
    'Dim Thread_UploadLogReader As New System.Threading.Thread(AddressOf readlog)
    'Thread_UploadLogReader.Start()
    End Sub
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
    End Sub
    Public Sub readlog()
    Using reader As New StreamReader(New FileStream("C:\logtest\test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    'start at the end of the file
    Dim lastMaxOffset As Long = reader.BaseStream.Length
    
    Do
    System.Threading.Thread.Sleep(100)
    
    'if the file size has not changed, idle
    If reader.BaseStream.Length = lastMaxOffset Then
    Continue Do
    End If
    
    'seek to the last max offset
    reader.BaseStream.Seek(lastMaxOffset, SeekOrigin.Begin)
    
    'read out of the file until the EOF
    Dim line As String = ""
    line = reader.ReadLine()
    Do While line IsNot Nothing
    TextBox1.AppendText(line)
    line = reader.ReadLine(line)
    Loop
    
    'update the last max offset
    lastMaxOffset = reader.BaseStream.Position
    Loop
    
    End Using
    End Sub
    End Class 
     
    shuggans says thanks.
  3. shuggans

    Joined:
    Dec 22, 2007
    Messages:
    184 (0.05/day)
    Thanks Received:
    7
    Location:
    Central Nebraska
    Gahhh

    Ive messed with this for so long. Is this even possible to do in a windows form? Moving the thread start to the button click event produced the same results. :banghead:
     
  4. FordGT90Concept

    FordGT90Concept "I go fast!1!11!1!"

    Joined:
    Oct 13, 2008
    Messages:
    20,379 (6.31/day)
    Thanks Received:
    9,504
    Location:
    IA, USA
    I wrote a class quickly to do what you are asking for with an example form of how to implement it...


    Basically, add MonitorFileForChanges.vb to your project then, for each file you want to monitor, do something like:

    Code:
    Private WithEvents file1 As New MonitorFileForChanges("Path to file1")
    Private WithEvents file2 As New MonitorFileForChanges("Path to file2")
    Private WithEvents file3 As New MonitorFileForChanges("Path to file3")
    Next, you'll have to start the workers. This is done by simply calling file1.StartWorker(), file2.StartWorker(), and file3.StartWorker().

    The toughest part is avoiding that nasty cross-thread reference. The code below basically detects if a thread that isn't itself is accessing the method and if so, it runs it from itself (yeah, that's complex). I bolded the bits that need to change for each one. You should use more descriptive names than file1, file2, and file3, obviously:

    Code:
        Public Sub [b]File1[/b]_LineAdded(ByVal line) Handles [b]file1[/b].LineAdded
            If Me.InvokeRequired Then
                Me.Invoke(New LineAddedHandler(AddressOf [b]File1[/b]_LineAdded), line)
            Else
                [b]ListBox1.Items[/b].Add(line)
            End If
        End Sub
    
        Public Sub [b]File2[/b]_LineAdded(ByVal line) Handles [b]file2[/b].LineAdded
            If Me.InvokeRequired Then
                Me.Invoke(New LineAddedHandler(AddressOf [b]File2[/b]_LineAdded), line)
            Else
                [b]ListBox2.Items[/b].Add(line)
            End If
        End Sub
    
        Public Sub [b]File3[/b]_LineAdded(ByVal line) Handles [b]file3[/b].LineAdded
            If Me.InvokeRequired Then
                Me.Invoke(New LineAddedHandler(AddressOf [b]File3[/b]_LineAdded), line)
            Else
                [b]ListBox3.Items[/b].Add(line)
            End If
        End Sub
    Finally, those worker threads work in a more-or-less infinite loop. This means you have to stop them or else your application won't close when it is told to close. You can do this by creating a handle to the FormClosing event and then call file1.StopWorker(), file2.StopWorker(), and file3.StopWorker() like so:

    Code:
        Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
            file1.StopWorker()
            file2.StopWorker()
            file3.StopWorker()
        End Sub
    Now, if a line is added to any of three files, it will show up in ListBox1-3.
     

    Attached Files:

    shuggans and Kreij say thanks.
    Crunching for Team TPU
  5. Kreij

    Kreij Senior Monkey Moderator Staff Member

    Joined:
    Feb 6, 2007
    Messages:
    13,817 (3.59/day)
    Thanks Received:
    5,629
    Location:
    Cheeseland (Wisconsin, USA)
    Nice Ford. I thought you quit coding for awhile to play games. :D
     
    10 Year Member at TPU
  6. FordGT90Concept

    FordGT90Concept "I go fast!1!11!1!"

    Joined:
    Oct 13, 2008
    Messages:
    20,379 (6.31/day)
    Thanks Received:
    9,504
    Location:
    IA, USA
    Beyond Good & Evil lost its pull on me. :(

    3 more days to From Dust...
     
    shuggans says thanks.
    Crunching for Team TPU
  7. shuggans

    Joined:
    Dec 22, 2007
    Messages:
    184 (0.05/day)
    Thanks Received:
    7
    Location:
    Central Nebraska
    Wow. Just tried abandoning my code and trying this...

    Code:
    Imports System.IO
    Imports System.Threading
    
    Public Class Form1
    
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
        End Sub
    
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Timer1.Interval = 100
            Timer1.Start()
        End Sub
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Using reader As New StreamReader(New FileStream("C:\logs\UploadLog.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                TextBox1.Text = reader.ReadToEnd
            End Using
    
        End Sub
    
    
    End Class 
    
    And it works beautifully. Sorry to take up your time Ford :s.
    Two questions with this though
    1. Am I correct in thinking each timer uses and starts its own thread automatically?
    2. How do I lock the scrollbars on a textbox to the bottom of the textbox?
     
  8. shuggans

    Joined:
    Dec 22, 2007
    Messages:
    184 (0.05/day)
    Thanks Received:
    7
    Location:
    Central Nebraska
    Question about multithreading in vb.net

    When I start A new thread for a subroutine to run on, should I start the new thread in that subroutine, or in the event that calls the subroutine?
     
  9. FordGT90Concept

    FordGT90Concept "I go fast!1!11!1!"

    Joined:
    Oct 13, 2008
    Messages:
    20,379 (6.31/day)
    Thanks Received:
    9,504
    Location:
    IA, USA
    1. Yes.
    2. After updating the text...
    Code:
    TextBox1.SelectionStart = TextBox1.Text.Length
    TextBox1.ScrollToCaret()
    Just beware that ReadToEnd() and using a TextBox will start to slow down after about 32 KiB of data are read.
     
    Crunching for Team TPU
  10. FordGT90Concept

    FordGT90Concept "I go fast!1!11!1!"

    Joined:
    Oct 13, 2008
    Messages:
    20,379 (6.31/day)
    Thanks Received:
    9,504
    Location:
    IA, USA
    The form is always on the "main" thread. It will own the thread(s) it starts.

    Usually you don't start threads inside of threads unless they are doing something special/different.

    You need to start work threads from somewhere in the main thread. It doesn't particularlly matter where.

    You'll get circular logic if you try to start a thread from inside itself. In fact, it would probably never even start in the first place.
     
    Crunching for Team TPU
  11. shuggans

    Joined:
    Dec 22, 2007
    Messages:
    184 (0.05/day)
    Thanks Received:
    7
    Location:
    Central Nebraska
    Write to a text file without streamwriter?

    Ok. This is the last piece holding me up.
    Is there ANY way I can write to a text file without locking it in use? Im currently using streamwriter- I need a different method to do so. Is this possible? would using a cmd to append a string be the best way, and if so is there a way to do it without causing a CMD window to pop up?? and what are some more alternatives?
    Thanks in advance
     
  12. FordGT90Concept

    FordGT90Concept "I go fast!1!11!1!"

    Joined:
    Oct 13, 2008
    Messages:
    20,379 (6.31/day)
    Thanks Received:
    9,504
    Location:
    IA, USA
    Crunching for Team TPU

Currently Active Users Viewing This Thread: 1 (0 members and 1 guest)