【问题标题】:Why VB.NET simple app takes forever to load several lines为什么 VB.NET 简单的应用程序需要永远加载几行
【发布时间】:2013-02-26 00:48:50
【问题描述】:

我有一个超级简单的脚本,用于将我们多年来从捐赠者那里收集的一长串电话号码分成单独的区号文件。

显然,当您有近 100 万行时,这将需要一段时间 - 但是 - 如果我输入 1,000 行,则需要不到一秒钟的时间。一旦我投入 100 万,只需要 10 秒就可以完成 5 行。这怎么可能?

Imports System.IO
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
    BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
    Dim lines As String
    lines = RichTextBox1.Lines.Count
    Dim looper As String = 0
    Dim path As String = "c:\acs\"
    MsgBox("I have " + lines + " lines to do.")
    If (Not System.IO.Directory.Exists(path)) Then
        System.IO.Directory.CreateDirectory(path)
    End If
    Dim i As String = 0

    For loops As Integer = 0 To RichTextBox1.Lines.Count - 1
        Dim ac As String = RichTextBox1.Lines(looper).ToString
        ac = ac.Substring(0, 3)
        Dim strFile As String = path + ac + ".txt"
        Dim sw As StreamWriter
        sw = File.AppendText(strFile)
        sw.WriteLine(RichTextBox1.Lines(looper))
        sw.Close()
        Label1.Text = String.Format("Processing item {0} of {1}", looper, lines)
        looper = looper + 1
    Next
    MsgBox("done now")
End Sub

结束类

【问题讨论】:

  • 这可能是将整个文件加载到内存中。尝试逐行阅读或拆分成更小的文件。
  • 正如其他人在下面暗示的那样,我的建议是不要为此使用 rtb,不太确定它作为 web 开发人员是什么,但有一种非常标准的方式来处理文件读取:@ 987654321@。我从来没有遇到过 SR 对象的性能问题,但是...msdn.microsoft.com/en-us/library/system.io.bufferedstream.aspx 提供了一种添加缓冲区的方法,尽管我很确定 SR 对象已经有了一些保护措施。

标签: vb.net performance while-loop richtextbox lines


【解决方案1】:

每次使用 RichTextBox.Lines 属性时,VB.Net 都需要通过 CR+LF 对来分割内容。因此,您的 For loops As Integer = - To RichTextBox1.Lines.Count-1 确实是一个性能打击。 尝试使用:

For Each vsLine As String in RichTextBox1.Lines

相反。它会快很多。或者,如果您必须使用 For 循环,则获取一次:

Dim vasLines() As String = RichTextBox1.Lines
For viLines As Integer = 0 to UBound(vasLines.Count)
    '....
Next

改为。

【讨论】:

    【解决方案2】:

    首先,您在 For 循环中执行 UI 更新。这需要时间。

    您在不是主线程的线程中更新 UI,这可能会影响性能。您不应使用 CheckForIllegalCrossThreadCalls 方法。您应该使用 BackgroundWorker 的 ReportProgress 方法正确更新 UI。

    您正在为循环的每次迭代打开和关闭一个文件。这也需要时间。

    我认为更好的方法是将数据添加到 Dictionary(Of String, List(Of String)) 中,以区号作为键,列表将包含该区号的所有数字。一旦字典被填满,循环遍历键并写出数字。

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-03
      • 1970-01-01
      相关资源
      最近更新 更多