Results 1 to 13 of 13

Thread: Working with Threads

  1. #1

    Thread Starter
    Addicted Member sinner0636's Avatar
    Join Date
    Sep 2009
    Posts
    233

    Working with Threads

    Hello
    this is my first time working with threads in VB.Net!
    I have a function that scans the windows directory for .log files and grabs them all then lists them to a listview.I have added a thread to help keep the UI updated and not lock up! Now if i use the DoEvents in the thread it does not lock up as much but why the DoEvents shouldn't the Thread Sleep keep it from locking up without the DoEvents or am i doing something wrong with the thread thanks?


    Code:
    Imports System.IO
    Imports System.Threading
    
    Public Class Form1
        Public MyThread As Threading.Thread
    
        Public Shared Function GetFilesRecursive(ByVal initial As String) As List(Of String)
            ' This list stores the results.
            Dim result As New List(Of String)
            ' This stack stores the directories to process.
            Dim stack As New Stack(Of String)
            ' Add the initial directory
            stack.Push(initial)
            ' Continue processing for each stacked directory
            Do While (stack.Count > 0)
                ' Get top directory string
                Dim dir As String = stack.Pop
                Try
                    ' Add all immediate file paths
                    result.AddRange(Directory.GetFiles(dir, "*.log"))
                    ' Loop through all subdirectories and add them to the stack.
                    Dim directoryName As String
                    For Each directoryName In Directory.GetDirectories(dir)
                        stack.Push(directoryName)
                    Next
                    Application.DoEvents()
                    Threading.Thread.Sleep(0.1) 'put the thread to sleep
                Catch ex As Exception
                End Try
            Loop
            ' Return the list
            Return result
        End Function
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Form1.CheckForIllegalCrossThreadCalls = False
            Dim list As List(Of String) = GetFilesRecursive(Environment.GetFolderPath(Environment.SpecialFolder.Windows))
    
            MyThread = New Threading.Thread(AddressOf GetFilesRecursive)
            MyThread.Start()
    
            For Each path As String In list
                Application.DoEvents()
                ListView1.Items.Add(path)
            Next
        End Sub
    
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Try
                MyThread.Abort()
            Catch ex As Exception
            End Try
        End Sub
    End Class

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Working with Threads

    The problem is that you aren't using the thread at the time... you are calling the function directly (on the line Dim list ...), and that is causing the problems.

    What you should do is find a way to use GetFilesRecursive without having to wait on a result.

    An easy to understand way to do it is to use a BackgroundWorker instead of an explicit Thread, and in the DoWork event call the function and store the result into a module level variable, which you can then use to fill the ListView in the BackgroundWorkers Completed event.

  3. #3
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Working with Threads

    Also don't call DoEvents() ever, but particularly not from a thread.

    The purpose of DoEvents() is to let you sort of get away with executing long-running tasks on the UI thread. It does so by synchronously forcing the UI thread to exhaust its event loop.

    On the UI thread, this serves to let things like screen updates happen even if you're blocking the UI thread. Unfortunately it also means events can happen in a different order than you might expect. It's generally a sign of work that shouldn't be done on the UI thread.

    On another thread, it doesn't really do anything and might even crash. A worker thread doesn't have an event loop, so it doesn't have a message queue, and there's nothing to exhaust. Even if it doesn't crash, your worker thread isn't holding up the UI so it's clutter.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  4. #4

    Thread Starter
    Addicted Member sinner0636's Avatar
    Join Date
    Sep 2009
    Posts
    233

    Re: Working with Threads

    omg that works so much better with a background worker then a thread i dont even need doevents and it dont lock up nice thanks

    Code:
    Public Shared Function GetFilesRecursive(ByVal initial As String) As List(Of String)
            ' This list stores the results.
            Dim result As New List(Of String)
            ' This stack stores the directories to process.
            Dim stack As New Stack(Of String)
            ' Add the initial directory
            stack.Push(initial)
            ' Continue processing for each stacked directory
            Do While (stack.Count > 0)
                ' Get top directory string
                Dim dir As String = stack.Pop
                Try
                    ' Add all immediate file paths
                    result.AddRange(Directory.GetFiles(dir, "*.log"))
                    ' Loop through all subdirectories and add them to the stack.
                    Dim directoryName As String
                    For Each directoryName In Directory.GetDirectories(dir)
                        stack.Push(directoryName)
                    Next
                Catch ex As Exception
                End Try
            Loop
            ' Return the list
            Return result
        End Function
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            BackgroundWorker1.RunWorkerAsync()
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Form1.CheckForIllegalCrossThreadCalls = False
    
            Dim list As List(Of String) = GetFilesRecursive(Environment.GetFolderPath(Environment.SpecialFolder.Windows))
    
            For Each path As String In list
                ListView1.Items.Add(path)
            Next
        End Sub

  5. #5

    Thread Starter
    Addicted Member sinner0636's Avatar
    Join Date
    Sep 2009
    Posts
    233

    Re: Working with Threads

    this will be nice that i can now update a statusbar with the results this is what i have so far but i need to know how i can not have to use the CheckForIllegalCrossThreadCalls without getting errors the right way?


    Code:
    Imports System.IO
    
    Public Class Form1
    
        Public Shared Function GetFilesRecursive(ByVal initial As String, ByVal ScanLogs As Boolean) As List(Of String)
            ' This list stores the results.
            Dim result As New List(Of String)
            ' This stack stores the directories to process.
            Dim stack As New Stack(Of String)
            ' Add the initial directory
            stack.Push(initial)
            ' Continue processing for each stacked directory
            Do While (stack.Count > 0)
                ' Get top directory string
                Dim dir As String = stack.Pop
                Try
                    ' Add all immediate file paths
                    If ScanLogs Then
                        result.AddRange(Directory.GetFiles(dir, "*.log"))
                    Else
                        result.AddRange(Directory.GetFiles(dir, "*.*"))
                    End If
    
                    ' Loop through all subdirectories and add them to the stack.
                    Dim directoryName As String
                    For Each directoryName In Directory.GetDirectories(dir)
                        stack.Push(directoryName)
                    Next
                Catch ex As Exception
                End Try
            Loop
            ' Return the list
            Return result
        End Function
    
        Public Function AbsoluteFolderPath(ByVal FilePath As String) As String
            Try
                Dim f As FileInfo
                f = My.Computer.FileSystem.GetFileInfo(FilePath)
                Dim folderPath As String = f.DirectoryName
                Return folderPath
            Catch ex As Exception
                'err
            End Try
        End Function
    
        Public Function AbsoluteFilePath(ByVal FilePath As String) As String
            Try
                Dim f As FileInfo
                f = My.Computer.FileSystem.GetFileInfo(FilePath)
                Dim fileName As String = f.Name
                Return fileName
            Catch ex As Exception
                'err
            End Try
        End Function
    
        Public Function FilePathExt(ByVal FilePath As String) As String
            Try
                Dim f As FileInfo
                f = My.Computer.FileSystem.GetFileInfo(FilePath)
    
                Dim fileName As String = Path.GetExtension(f.Name)
                Return fileName
            Catch ex As Exception
                'err
            End Try
        End Function
    
        Public Function FormatBytes(ByVal FilePath As String) As String
            Dim BytesCaller As ULong
            Dim DoubleBytes As Double
            Try
                Dim f As FileInfo = My.Computer.FileSystem.GetFileInfo(FilePath)
    
                BytesCaller = f.Length
    
                Select Case BytesCaller
                    Case Is >= 1099511627776
                        DoubleBytes = CDbl(BytesCaller / 1099511627776) 'TB
                        Return FormatNumber(DoubleBytes, 2) & " TB"
                    Case 1073741824 To 1099511627775
                        DoubleBytes = CDbl(BytesCaller / 1073741824) 'GB
                        Return FormatNumber(DoubleBytes, 2) & " GB"
                    Case 1048576 To 1073741823
                        DoubleBytes = CDbl(BytesCaller / 1048576) 'MB
                        Return FormatNumber(DoubleBytes, 2) & " MB"
                    Case 1024 To 1048575
                        DoubleBytes = CDbl(BytesCaller / 1024) 'KB
                        Return FormatNumber(DoubleBytes, 2) & " KB"
                    Case 0 To 1023
                        DoubleBytes = BytesCaller ' bytes
                        Return FormatNumber(DoubleBytes, 2) & " bytes"
                    Case Else
                        Return ""
                End Select
            Catch ex As Exception
                Return ""
            End Try
        End Function
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            BackgroundWorker1.RunWorkerAsync()
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Form1.CheckForIllegalCrossThreadCalls = False
    
            Dim list As List(Of String) = GetFilesRecursive(Environment.GetFolderPath(Environment.SpecialFolder.Windows), True)
    
            For Each Item As String In list
    
                Dim ColumnItem As String() = New String(4) {}
                Dim itm As ListViewItem
    
                'Add Items To ListView
                ColumnItem(0) = AbsoluteFilePath(Item)
                ColumnItem(1) = FormatBytes(Item)
                ColumnItem(2) = FilePathExt(Item)
                ColumnItem(3) = Item
                itm = New ListViewItem(ColumnItem, 0)
    
                ListView1.Items.Add(itm)
                ListView1.Items(ListView1.CheckedItems.Count).Checked = True
            Next
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.ListView1.CheckBoxes = True
            Me.ListView1.FullRowSelect = True
            Me.ListView1.View = View.Details
    
            Me.ListView1.Columns.Add("Name", 200, HorizontalAlignment.Left)
            Me.ListView1.Columns.Add("Size", 100, HorizontalAlignment.Left)
            Me.ListView1.Columns.Add("Type", 100, HorizontalAlignment.Left)
            Me.ListView1.Columns.Add("Location", 4126, HorizontalAlignment.Left)
        End Sub
    End Class
    
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            MsgBox("Logs Found " + Str(ListView1.Items.Count))
        End Sub
    Last edited by sinner0636; Jan 9th, 2018 at 01:27 PM.

  6. #6
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Working with Threads

    Quote Originally Posted by sinner0636 View Post
    omg that works so much better with a background worker then a thread
    Threads are better if you need finer control, but a BackgroundWorker (which is just a nice wrapper around a thread) is easier to set up for simple cases like this one.

    Quote Originally Posted by sinner0636 View Post
    Code:
            MsgBox("Logs Found " + Str(ListView1.Items.Count))
    Is there a particular reason you want two spaces between the word Found and the count?

    The Str function does not convert things to String, it converts numbers to Strings and formats them in a particular way (including adding a leading space to positive numbers). You should be using CStr instead, or the .ToString method of the item you are converting, eg:
    Code:
            MsgBox("Logs Found " + CStr(ListView1.Items.Count))
            MsgBox("Logs Found " + ListView1.Items.Count.ToString())

  7. #7

    Thread Starter
    Addicted Member sinner0636's Avatar
    Join Date
    Sep 2009
    Posts
    233

    Re: Working with Threads

    srry i just edited my post above this one asking about the errors im getting with CheckForIllegalCrossThreadCalls oh ok i used real basic for years thought u use str to covert numbers to strings good to know ill use cstr for now on
    Last edited by sinner0636; Jan 9th, 2018 at 01:33 PM.

  8. #8
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Working with Threads

    The reason you are using CheckForIllegalCrossThreadCalls is because you are doing something Illegal... you are accessing a control (which belongs to the UI thread) from another thread (the BackgroundWorkers DoWork event).

    One way to avoid it here is to move the ListView code to the RunWorkerCompleted event (which is back on the UI thread, after the BackgroundWorker has finished), and use a module level variable to use the data, eg:
    Code:
        Dim list As List(Of String)
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            list = GetFilesRecursive(Environment.GetFolderPath(Environment.SpecialFolder.Windows), True)
        End Sub
    
    
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
            For Each Item As String In list
    
                Dim ColumnItem As String() = New String(4) {}
                Dim itm As ListViewItem
    
                'Add Items To ListView
                ColumnItem(0) = AbsoluteFilePath(Item)
                ColumnItem(1) = FormatBytes(Item)
                ColumnItem(2) = FilePathExt(Item)
                ColumnItem(3) = Item
                itm = New ListViewItem(ColumnItem, 0)
    
                ListView1.Items.Add(itm)
                ListView1.Items(ListView1.CheckedItems.Count).Checked = True
            Next
    
            MsgBox("Logs Found " + Str(ListView1.Items.Count))
        End Sub
    This isn't a perfect solution, but it should be good enough for now.

  9. #9
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Working with Threads

    Here's a REALLY easy example of using a thread and having it update a progress bar on the main UI thread as it runs.
    Code:
        Private t As Threading.Thread
        Private myList As New List(Of String)
        Public Sub Button1_Clicked(sender As Object, e As EventArgs) Handles Button1.Click
            t = New Threading.Thread(AddressOf ThreadDoStuff) 'Says that when you start "t" then have it launch the "ThreadDoStuff" method.
            t.IsBackground = True 'Set it to run in the background.
            t.Start()  'Start it
    
            'Do other things or just wait...
            'Thread "t" is handling your computing so everything after this point is your main UI thread.
    
            'If it's not doing anything, it'll be free and responsive for the user to click things, and not "locked up".
        End Sub
    
        Private Sub ThreadDoStuff()
            'Thread "t" will start running this code when started.
            For i As Integer = 0 To myList.Count - 1
                'Do something
                UpdateProgressBar(i / myList.Count - 1)  'Call this to update the progress bar.  The math is just to give a 0 to 100 number.
            Next
        End Sub
    
        Private Delegate Sub Delegate_UpdateProgressBar(i As Double)  'Delegates is a system to "hand off" a task from one thread to another. 
        Private Sub UpdateProgressBar(i As Double)
            If ProgressBar1.InvokeRequired Then  'If the control we want to update detects a cross-thread operation, it needs to set up a delegate.
                Dim d As New Delegate_UpdateProgressBar(AddressOf UpdateProgressBar) 'Make a new delegate and point it back to this method.
                ProgressBar1.Invoke(d, {i}) 'Tell the UI thread to invoke the delegate with "i" as the parameters.
                ' So when the UI thread re-runs this subroutine via the delegate, it will 
                'go to the "else" part...
            Else
                ProgressBar1.Value = i  'Update the progress bar with a number between 0 and 100.
            End If
        End Sub
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  10. #10

    Thread Starter
    Addicted Member sinner0636's Avatar
    Join Date
    Sep 2009
    Posts
    233

    Re: Working with Threads

    ok thats what im looking for works perfect only having one more issue with the background worker is that i cant seem to scan multiple paths at one time seems i can only scan one a time to get results in the complete event how can i fix this?

    Can only scan one of these paths in the code below this

    Code:
     For Each SpecialPath As String In SpecialFolders  'Scan special paths
                list = GetFilesRecursive(SpecialPath, False)
            Next
    
            list = GetFilesRecursive(Windows, True)  ' Only scan for windows logs
    Code:
        Public Cookies As String = (Environment.GetFolderPath(Environment.SpecialFolder.Cookies))
        Public History As String = (Environment.GetFolderPath(Environment.SpecialFolder.History))
        Public IECache As String = (Environment.GetFolderPath(Environment.SpecialFolder.InternetCache))
        Public WinTemp As String = (Environment.GetFolderPath(Environment.SpecialFolder.Windows)) + "\Temp"
        Public Prefetch As String = (Environment.GetFolderPath(Environment.SpecialFolder.Windows)) + "\Prefetch"
        Public UserTemp As String = (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) + "\Temp"
        Public Recent As String = (Environment.GetFolderPath(Environment.SpecialFolder.Recent))
        Public Windows As String = (Environment.GetFolderPath(Environment.SpecialFolder.Windows))
    
        Public SpecialFolders As String() = {Cookies, History, IECache, WinTemp, Prefetch, UserTemp, Recent}
    
     Public Shared Function GetFilesRecursive(ByVal initial As String, ByVal ScanLogs As Boolean) As List(Of String)
            ' This list stores the results.
            Dim result As New List(Of String)
            ' This stack stores the directories to process.
            Dim stack As New Stack(Of String)
            ' Add the initial directory
            stack.Push(initial)
            ' Continue processing for each stacked directory
            Do While (stack.Count > 0)
                ' Get top directory string
                Dim dir As String = stack.Pop
                Try
    
                    ' Add all immediate file paths
    
                    If ScanLogs = False Then
                        result.AddRange(Directory.GetFiles(dir, "*.*"))
                    ElseIf ScanLogs = True Then
                        result.AddRange(Directory.GetFiles(dir, "*.log"))
                    End If
    
                    ' Loop through all subdirectories and add them to the stack.
                    Dim directoryName As String
                    For Each directoryName In Directory.GetDirectories(dir)
                        stack.Push(directoryName)
                    Next
                Catch ex As Exception
                End Try
            Loop
            ' Return the list
            Return result
        End Function
    
      Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            For Each SpecialPath As String In SpecialFolders
                list = GetFilesRecursive(SpecialPath, False)
            Next
    
            list = GetFilesRecursive(Windows, True)
        End Sub
    
      Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    
            Dim imageList As New ImageList
            Dim ListIcon As String = ("C:\Micro Cleaner\AppIcons\Shield.png")
    
            If DirExists(ListIcon) Then
                imageList.Images.Add(Bitmap.FromFile(ListIcon))
                ListView1.SmallImageList = imageList
            End If
    
            Try
                For Each Item As String In list
                    Dim ColumnItem As String() = New String(4) {}
                    Dim itm As ListViewItem
    
                    'Add Items To ListView
                    ColumnItem(0) = AbsoluteFilePath(Item)
                    ColumnItem(1) = FormatBytes(Item)
                    ColumnItem(2) = FilePathExt(Item)
                    ColumnItem(3) = Item
                    itm = New ListViewItem(ColumnItem, 0)
    
                    ListView1.Items.Add(itm)
                    ListView1.Items(ListView1.CheckedItems.Count).Checked = True
                Next
    
                MsgBox("Logs Found " + CStr(ListView1.Items.Count))
            Catch ex As Exception
                'err
            End Try
        End Sub
    Last edited by sinner0636; Jan 9th, 2018 at 03:33 PM.

  11. #11
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Working with Threads

    Quote Originally Posted by sinner0636 View Post
    ok thats what im looking for works perfect only having one more issue with the background worker is that i cant seem to scan multiple paths at one time seems i can only scan one a time to get results in the complete event how can i fix this?

    Code:
    ...
      Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            For Each SpecialPath As String In SpecialFolders
                list = GetFilesRecursive(SpecialPath, False)
            Next
    
            list = GetFilesRecursive(Windows, True)
        End Sub
    ...
    You are overwriting the list each time, because you are assigning the return value to the variable each time.

    Try something like this instead:
    Code:
    ...
      Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            Dim tempList as List(Of String)
            For Each SpecialPath As String In SpecialFolders
                tempList = GetFilesRecursive(SpecialPath, False)
                list.AddRange(tempList)
            Next
    
            tempList = GetFilesRecursive(Windows, True)
            list.AddRange(tempList)
        End Sub
    ...
    Alternatively you could modify GetFilesRecursive so that it adds to a list that you pass in, but that could easily cause more work.

  12. #12

    Thread Starter
    Addicted Member sinner0636's Avatar
    Join Date
    Sep 2009
    Posts
    233

    Re: Working with Threads

    made the logs and all items from special folders list separate more easy to read it lists them adds the logs fine but only adds the last path in the array of special folders "Recent files"

    Code:
        Public Cookies As String = (Environment.GetFolderPath(Environment.SpecialFolder.Cookies))
        Public History As String = (Environment.GetFolderPath(Environment.SpecialFolder.History))
        Public IECache As String = (Environment.GetFolderPath(Environment.SpecialFolder.InternetCache))
        Public WinTemp As String = (Environment.GetFolderPath(Environment.SpecialFolder.Windows)) + "\Temp"
        Public Prefetch As String = (Environment.GetFolderPath(Environment.SpecialFolder.Windows)) + "\Prefetch"
        Public UserTemp As String = (Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)) + "\Temp"
        Public Recent As String = (Environment.GetFolderPath(Environment.SpecialFolder.Recent))
        Public Windows As String = (Environment.GetFolderPath(Environment.SpecialFolder.Windows))
    
        Public SpecialFolders As String() = {Cookies, History, IECache, WinTemp, Prefetch, UserTemp, Recent}
    
        Public SpecialList As List(Of String)
        Public LogList As List(Of String)
    Code:
        Public Shared Function ScanSpecialFolders(ByVal initial As String) As List(Of String)
            ' This list stores the results.
            Dim result As New List(Of String)
            ' This stack stores the directories to process.
            Dim stack As New Stack(Of String)
            ' Add the initial directory
            stack.Push(initial)
            ' Continue processing for each stacked directory
            Do While (stack.Count > 0)
                ' Get top directory string
                Dim dir As String = stack.Pop
                Try
                    ' Add all immediate file paths
                    result.AddRange(Directory.GetFiles(dir, "*.*"))
    
                    ' Loop through all subdirectories and add them to the stack.
                    Dim directoryName As String
                    For Each directoryName In Directory.GetDirectories(dir)
                        stack.Push(directoryName)
                    Next
                Catch ex As Exception
                End Try
            Loop
            ' Return the list
            Return result
        End Function
    
        Public Shared Function ScanWindowsLogs(ByVal initial As String) As List(Of String)
            ' This list stores the results.
            Dim result As New List(Of String)
            ' This stack stores the directories to process.
            Dim stack As New Stack(Of String)
            ' Add the initial directory
            stack.Push(initial)
            ' Continue processing for each stacked directory
            Do While (stack.Count > 0)
                ' Get top directory string
                Dim dir As String = stack.Pop
                Try
                    ' Add all immediate file paths
                    result.AddRange(Directory.GetFiles(dir, "*.log"))
    
                    ' Loop through all subdirectories and add them to the stack.
                    Dim directoryName As String
                    For Each directoryName In Directory.GetDirectories(dir)
                        stack.Push(directoryName)
                    Next
                Catch ex As Exception
                End Try
            Loop
            ' Return the list
            Return result
        End Function
    Code:
        Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            'Scan Special Folders
            For Each SpecialPath As String In SpecialFolders
                Speciallist = ScanSpecialFolders(SpecialPath)
            Next
    
            'Scan Windows Logs
            LogList = ScanWindowsLogs(Windows)
        End Sub
    Code:
       Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    
            Dim imageList As New ImageList
            Dim ListIcon As String = ("C:\Micro Cleaner\AppIcons\Shield.png")
    
            If DirExists(ListIcon) Then
                imageList.Images.Add(Bitmap.FromFile(ListIcon))
                ListView1.SmallImageList = imageList
            End If
    
            Try
                'LOAD SPECIAL FILES
                For Each SpecialItem As String In Speciallist
                    Dim SpecialColumnItem As String() = New String(4) {}
                    Dim Speicalitm As ListViewItem
    
                    'Add Items To ListView
                    SpecialColumnItem(0) = AbsoluteFilePath(SpecialItem)
                    SpecialColumnItem(1) = FormatBytes(SpecialItem)
                    SpecialColumnItem(2) = FilePathExt(SpecialItem)
                    SpecialColumnItem(3) = SpecialItem
                    Speicalitm = New ListViewItem(SpecialColumnItem, 0)
    
                    ListView1.Items.Add(Speicalitm)
                    ListView1.Items(ListView1.CheckedItems.Count).Checked = True
                Next
    
                'LOAD WINDOWS LOGS
                For Each LogItem As String In LogList
                    Dim LogColumnItem As String() = New String(4) {}
                    Dim Logitm As ListViewItem
    
                    'Add Items To ListView
                    LogColumnItem(0) = AbsoluteFilePath(LogItem)
                    LogColumnItem(1) = FormatBytes(LogItem)
                    LogColumnItem(2) = FilePathExt(LogItem)
                    LogColumnItem(3) = LogItem
                    Logitm = New ListViewItem(LogColumnItem, 0)
    
                    ListView1.Items.Add(Logitm)
                    ListView1.Items(ListView1.CheckedItems.Count).Checked = True
                Next
    
                MsgBox("Files Found: " + CStr(ListView1.Items.Count))
            Catch ex As Exception
                'err
            End Try
        End Sub
    Last edited by sinner0636; Jan 9th, 2018 at 04:28 PM.

  13. #13
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Working with Threads

    BackgroundWorker1_DoWork has the same issue as before... it is overwriting the variable, but this time only for each item in the loop (and no longer for the item after the loop).

    The solution is the same as my previous post.

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