Home > Articles > Programming > Windows Programming

  • Print
  • + Share This
From the author of

The Single-Threaded Example

As you become more familiar with multithreading, you will be able to start working directly on an application design that uses this technique. As a start, however, I recommend designing the process as if it will occur all on a single thread. When you have a system working in a single-threaded or synchronous model, you can then make the necessary changes to turn it into a system that uses background processing. I will follow this path myself in this article, building an application without any background work and then converting that as required.

For the purposes of this article, I will be using the previous example, an application that needs to scan the hard drive for music files and load up a list view with its findings. So, without going through any proper design process (although you can pretend that I did, if you would like), I'll jump right into coding the single-threaded version of this file scanner. Now, the way I like to develop, whether I am working from a design or just writing a quick example like this, is to create the important functionality first, without complicating the issue by worrying about the user interface. In this case, that means I am going to write a file-scanning procedure that works but that is not necessarily the final version that will be used in conjunction with my Form. The module in Listing 1 (which could be compiled and used from the command line, if you want) illustrates the simple file-scan code on its own. As each file is found, it is added into a global ArrayList instance, which would contain the complete results of the scan at the end of the program.

Listing 1: Prototype File Scanner

Imports System
Imports System.IO

Module FileScanner
  Dim WMAFiles As New ArrayList()

  Sub Main()
    Console.WriteLine("{0} Files Found", WMAFiles.Count)
  End Sub

  Private Sub StartScan(ByVal filter As String)
    Dim directoriesToSearch As String()
    Dim currentDirectory As String
    directoriesToSearch = Directory.GetLogicalDrives()
    For Each currentDirectory In directoriesToSearch
      SearchForFiles(currentDirectory, True, filter)
  End Sub

  Private Sub SearchForFiles(ByVal dir As String, _
                ByVal subdirectories As Boolean, _
                ByVal filter As String)
    Dim foundFiles As String()
    Dim foundFile As String
      foundFiles = Directory.GetFiles(dir, filter)
      For Each foundFile In foundFiles
      If subdirectories Then
        Dim foundDirs As String()
        Dim currentDir As String
        foundDirs = Directory.GetDirectories(dir)
        For Each currentDir In foundDirs
          SearchForFiles(currentDir, _
            subdirectories, filter)
      End If
      'If I'm not allowed access 
      'to a file or folder due to
      'security or a missing volume,
      'then I want to just ignore it.
    End Try
  End Sub

End Module

To convert this code for use with a Windows Forms interface, you could start the scan in the Load event of the Form and then bind or copy the contents of the ArrayList to a user interface element such as a ListBox. You would require the same two procedures, StartScan and SearchForFiles, and a global instance of the ArrayList, as in Listing 1, but the code in the Load event of the Form would look like this:

  Dim WMAFiles As New ArrayList()

  Private Sub frmWMAList_Load(ByVal sender As Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load
    lbFiles.DataSource = WMAFiles
  End Sub

The end result of this first version of the code will be that the scan occurs before the Form is ever displayed, causing a delay in the application startup. Converting this code into a multithreaded version is the best way to minimize that startup delay, presenting the user with an interface as quickly as possible.

  • + Share This
  • 🔖 Save To Your Account