【问题标题】:How to load items from text file into listbox using multiple thread如何使用多线程将文本文件中的项目加载到列表框中
【发布时间】:2015-07-08 08:02:38
【问题描述】:

我目前正在使用以下代码将文本文件项加载到我的一个应用程序的列表框中,它可以工作,但该文本文件的大小超过 10mb。所以应用程序在将项目加载到列表框时卡住了几秒钟。

一旦项目被加载,它就可以正常工作。那么有什么方法可以减少加载时间并防止应用程序挂起。

Public Sub loadfiles()
    Dim systemdrv As String = Mid(Environment.GetFolderPath(Environment.SpecialFolder.System), 1, 3)
    Dim r As IO.StreamReader
    r = New IO.StreamReader(systemdrv + "temp\test.txt")
    While (r.Peek() > -1)
        ListBox2.Items.Add(r.ReadLine)
    End While
    r.Close()
End Sub

我读到一些是使用多个线程可以解决问题。所以我尝试了几件事,但每次都失败了......

【问题讨论】:

    标签: vb.net multithreading listbox


    【解决方案1】:

    对单个文件的多次读取并不是真正的解决方案,在大多数情况下,您不会减少加载时间,因为对存储的访问实际上是顺序的。 但是,您可以防止应用程序挂起,只需包裹在 BackgroundWorkerAction 中。

    请注意,在 Windows 窗体中,只有创建窗体的主线程才能修改窗体中的任何组件,因此您需要将结果存储在附加变量中或将每个修改操作包装在委托中。如果您想保持加载效果(有助于为客户端提供工作效果),您可以使用 Delegate 包装在 BackgroundWorker 中。

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim systemdrv As String = Mid(Environment.GetFolderPath(Environment.SpecialFolder.System), 1, 3)
        Dim r As IO.StreamReader
        r = New IO.StreamReader(systemdrv + "temp\test.txt")
        While (r.Peek() > -1)
            Dim line As String = r.ReadLine
            If ListBox2.InvokeRequired Then
                Listbox2.Invoke(Sub() ListBox2.Items.Add(line))
            Else
                ListBox2.Items.Add(line)
        End While
        r.Close()
    End Sub
    

    【讨论】:

      【解决方案2】:

      您可以同时使用两个线程或后台工作人员

      您将需要编辑您的代码,但无法从另一个线程更新 UI,因此请将您读取的行保存到数组中或使用 File.ReadAllLines(path) 方法直接返回一个数组,而不是将它们直接添加到列表框中。

      我将使用后台工作程序,因为它在完成其工作时会引发一个事件,并且您需要知道何时可以将项目添加到列表框,所以:

      添加一个后台worker并使用它的事件DoWork()RunWorkerCompleted()分别读取文本行并将数组放入列表框:

      Dim readText() as String
      Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
          Dim systemdrv As String = Mid(Environment.GetFolderPath(Environment.SpecialFolder.System), 1, 3)
          readText = IO.File.ReadAllLines(systemdrv + "temp\test.txt")
      End Sub
      
      Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
          ListBox2.Items.AddRange(readText)
      End Sub
      

      现在从您要开始读取文件的位置添加(form_load、button_click):

      BackgroundWorker1.RunWorkerAsync()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多