Vb.net 如何使用多线程将项目从文本文件加载到列表框中

Vb.net 如何使用多线程将项目从文本文件加载到列表框中,vb.net,multithreading,listbox,Vb.net,Multithreading,Listbox,我目前正在使用以下代码将文本文件项加载到我的一个应用程序的listbox中,它可以工作,但该文本文件的大小超过10mb。因此,在将项目加载到listbox时,应用程序停滞了几秒钟 一旦物品被装载,它就可以正常工作。那么有没有办法减少加载时间并防止应用程序挂起呢 Public Sub loadfiles() Dim systemdrv As String = Mid(Environment.GetFolderPath(Environment.SpecialFolder.System), 1

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

一旦物品被装载,它就可以正常工作。那么有没有办法减少加载时间并防止应用程序挂起呢

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

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

您可以同时使用两个线程或backgroundworker

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

我将使用backgroundworker,因为它在完成其工作时会引发事件,并且您需要知道何时可以向列表框添加项,以便:

添加一个后台工作程序,并使用其事件
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
现在从要开始读取文件的位置添加(表单加载,按钮单击):


您可以同时使用两个线程或backgroundworker

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

我将使用backgroundworker,因为它在完成其工作时会引发事件,并且您需要知道何时可以向列表框添加项,以便:

添加一个后台工作程序,并使用其事件
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
现在从要开始读取文件的位置添加(表单加载,按钮单击):


您可以同时使用两个线程或backgroundworker

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

我将使用backgroundworker,因为它在完成其工作时会引发事件,并且您需要知道何时可以向列表框添加项,以便:

添加一个后台工作程序,并使用其事件
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
现在从要开始读取文件的位置添加(表单加载,按钮单击):


您可以同时使用两个线程或backgroundworker

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

我将使用backgroundworker,因为它在完成其工作时会引发事件,并且您需要知道何时可以向列表框添加项,以便:

添加一个后台工作程序,并使用其事件
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
现在从要开始读取文件的位置添加(表单加载,按钮单击):


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

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

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

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

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

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

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

请注意,在Windows窗体中,只有创建窗体的主线程才能修改窗体中的任何组件,因此您需要将结果存储在附加变量中,或将每个修改操作包装到委托中。如果要保持加载效果(提供有用的