【问题标题】:ASP.NET MVC FileContentResult SLOWASP.NET MVC FileContentResult 慢
【发布时间】:2010-08-03 17:05:35
【问题描述】:

我们正在使用它来返回文件以进行导出。当我们对大量记录运行此导出时,它需要将近 10 分钟才能运行。下面是一段实际调用File()方法并返回结果的代码sn-p。

Public Function Export(ByVal ID As Integer) As FileContentResult
  Dim str As String = String.Empty
  Dim data() As Byte
  Dim r As New ExportResult
  Dim Test As New TestConnection(WebUtil.UserToken)

  'This line is important coz IE download was prevented without this.
  ControllerContext.HttpContext.Response.ClearHeaders()

  r = Test.ExportFile(ID)
  data = Encoding.ASCII.GetBytes(r.ResponseString)

  Return File(data, "text/plain", r.DefaultFileName)

End Function

实际的 ExportFile 方法接受一个 ID,调用另一个方法,从数据库中获取一堆记录,对每一行执行一堆计算,然后创建一个 StringBuilder,并为每一行填充 StringBuilder,然后在执行 .ToString() 之后,将其弹出到 List(Of String) 中。然后此方法将 List(Of String) 返回给 ExportFile 方法,此方法创建另一个 StringBuilder,附加该列表中的所有字符串,将其转换为一个大字符串,并将其设置为结果的 ResponseString 属性('r ' 在上面的代码中)。

这就是它的工作原理。有没有办法加快这个过程,比如很多?

-斯科特

编辑:更多代码

Public Function ExportFile(ByVal ID As Integer) As ExportResult
            Dim result As New ExportResult
            Dim s As New StringBuilder

            'Get all Records
            Dim dt As New DataTable
            Using dal As New SQL
                dal.Parameters.AddWithValue("@ID", ID)
                dal.Execute("[dbo].[uspGet]", dt)
                dal.Parameters.Clear()
            End Using

            Dim dataobj As New DataObj(dt, ID)

            'Create FileName
            If dt.Rows.Count > 0 Then
                Dim StartDate As DateTime = DateTime.Parse(dt.Rows(0).Item("StartDate"))
                Dim EndDate As DateTime = DateTime.Parse(dt.Rows(0).Item("EndDate"))
                result.DefaultFileName = String.Format("HMDA_{0}_{1}.dat", String.Format("{0:MMyyyy}", StartDate), String.Format("{0:MMyyyy}", EndDate))
            End If

            'Add Title Line
            s.AppendLine(dataobj.CreateTitleLine())

            'Add all Record Lines
            Dim records As List(Of String) = dataobj.CreateRecordLines()
            Dim last As Integer = records.Count - 1
            For i = 0 To last
                If i = last Then
                    s.Append(records(i))
                Else
                    s.AppendLine(records(i))
                End If
            Next

            result.ResponseString = s.ToString

            Return result
End Function

【问题讨论】:

    标签: asp.net-mvc string file-io stringbuilder filecontentresult


    【解决方案1】:

    您的 SQL 性能如何?我会开始在那里检查你的问题。

    然后考虑您的文件有多大。数据仍然需要在客户端下载。

    【讨论】:

    • 当我运行操作中使用的 SQL 查询时,它们会立即运行。输出的文件大小为 1.16MB(所有文本)。我认为减速来自于 StringBuilder 列表的巨大规模,然后当该列表附加到单个 StringBuilder 中,然后在其上运行 .ToString() 时。我只是不知道如何让一切运行得更快。
    • @Scott,然后发布更多代码。没有人可以优化他们看不到的东西。
    • 刚刚贴出了ExportFile()函数的代码。这适用于实际创建对象的类,然后此方法将结果返回给我首先发布的方法。
    • @Scott,我看到了代码,这里有些问题。 1.1MB 的字符串不应该那么慢。
    【解决方案2】:

    避免额外的副本?也许您可以避免转换为字节和/或创建文件。无需额外工作,只需将字符串写入响应即可。

    【讨论】:

    • 所以你的说法不是将它包含在结果中,而是直接返回它?由于 FileContentResult 的工作方式,字节转换仍然必须发生,但从技术上讲,我只需要 String 值。我们将其存储在结果中的主要原因是代码可读性。你认为这会大有帮助吗?
    猜你喜欢
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多