我目前正在使用以下代码将文本文件项加载到我的某个应用程序的列表框中,但它可以正常工作,但该文本文件的大小超过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
我读过一些使用多线程可以解决问题的方法。所以我尝试了一些但每次都失败了......
答案 0 :(得分:2)
对单个文件进行多次读取并不是一个真正的解决方案,在大多数情况下,由于访问存储事实上是顺序的,因此您无法减少加载时间。 但是,您可以阻止应用程序挂在BackgroundWorker或Action中。
请注意,在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
答案 1 :(得分:1)
您可以同时使用线程或背景工作者
您需要编辑代码,但是无法从另一个线程更新UI,因此将读取的行保存到数组中或使用将直接返回数组的File.ReadAllLines(path)方法将它们直接添加到列表框中。
我将使用后台工作程序,因为它在完成工作时会引发事件,您需要知道何时可以将项目添加到列表框中:
添加后台工作程序并使用其事件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
现在从你想要开始阅读文件add(form_load,button_click):
BackgroundWorker1.RunWorkerAsync()