【问题标题】:Datatable populating from webrequest extemly slow从 webrequest 填充数据表非常慢
【发布时间】:2014-03-28 12:13:00
【问题描述】:

VB.net 2013 中填充数据表时,我一直在研究一个极其缓慢的情况。

我有一个带有多个表的远程 MySQL 服务器。

作为示例,让我们假设一个名为 Student 的表包含 2 个字段。一个用于StudenID,另一个用于学生姓名。

下一个表用于课程,第一个表包含 2 个字段。一个用于 CourseID,另一个用于课程名称。

现在我们还有第三个表,其中包含多个字段,其中有 StudentID 和 CourseID。

所以我使用 SQL 语句对服务执行 httpRequest,该服务从第三个表中返回一个 Json 字符串,其中包含很多字段。

我可以读取和解码 Jsonstring,这很快,但由于我想显示学生和课程名称,我需要每行再执行 2 个 httpRequests 来联系服务器并使用 StudentID 获取他/她的姓名,然后使用 CourseID 获取课程名称,解码更多 Json 字符串。

我一切正常,数据网格按预期显示值,但是每行大约需要 1 秒非常慢。有时我们会得到 300 或更多的结果,这变得不切实际。

我很确定我没有使用正确的方法。如果有人可以帮助我,我会非常感激,因为我是 VB.net 的新手。

我的代码是这样的

我有一个模块,其中有一些与 http 相关的 utils 函数,在需要时我都会用到。

 Function HttpPost(url As String, query As String, alvara As String) As String
        ServicePointManager.UseNagleAlgorithm = True
        ServicePointManager.Expect100Continue = True
        ServicePointManager.CheckCertificateRevocationList = False
        ServicePointManager.DefaultConnectionLimit = 1000


        Dim request As WebRequest = WebRequest.Create(url & 3274 & "/service1.php")
        request.Method = "POST"
        request.ContentType = "text/xml"

        Dim postData As String = query
        Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
        request.ContentLength = byteArray.Length
        Dim dataStream As Stream = request.GetRequestStream()
        dataStream.Write(byteArray, 0, byteArray.Length)
        'dataStream.Close()

        Dim resposta As WebResponse = request.GetResponse()
        ' Console.WriteLine(CType(resposta, HttpWebResponse).StatusDescription)
        dataStream = resposta.GetResponseStream()
        Dim reader As New StreamReader(dataStream)
        Dim RespostaDoServidor As String = reader.ReadToEnd()
        If RespostaDoServidor = "0" Then
            MsgBox("Erro de Comunicação")
            Return RespostaDoServidor

        End If
        reader.Close()
        dataStream.Close()
        resposta.Close()

        Return RespostaDoServidor

    End Function

Function NomeDeAlunoPorID(IDAluno As Int16) As String
 ' return student Name using IDAluno

    Dim NomeDoAluno As String ' will be return value
    Dim resposta As String
    resposta = HttpPost("http://XXXXXXX.com/", "SELECT nome FROM aluno WHERE aluno_id='" & IDAluno & "' AND alvara='" & VariaveisGlobais.Alvara & "'", 3274)

    Dim Jresultado As JArray = JArray.Parse(resposta)
    Dim resultado As List(Of JToken) = Jresultado.Children().ToList() ' ficamos com uma lista dos campos

    ' loop por todos os campos de UM RECORD e adicionamos a uma HashTable
    For Each item As JObject In resultado
        Dim hash As Hashtable = New Hashtable

        For Each propriedade As JProperty In item.Properties()
            hash.Add(propriedade.Name, propriedade.Value.ToString)
        Next

        NomeDoAluno = hash.Item("nome")
        ' devolvemos o primero e único resultado possivel.
        Return NomeDoAluno
    Next

    ' se tivermos chegado aqui ocorreu um Erro
    NomeDoAluno = "Desconhecido"
    Return NomeDoAluno

End Function`

这个是给学生的,还有另一个类似的功能给 Instrutor (假设是我使用的那个例子中的课程名称。

我从主代码中调用此函数来填充数据表并显示数据网格视图:

Private Sub PreparaTabelaUtilizacaoViatura()

    BtnEditar.Enabled = False
    btnGravar.Enabled = False
    ' formatar as grid
    dgvAnaliseDeUtilização.MultiSelect = False
    dgvAnaliseDeUtilização.DefaultCellStyle.SelectionBackColor = Color.MidnightBlue
    dgvAnaliseDeUtilização.DefaultCellStyle.SelectionForeColor = Color.Lavender
    dgvAnaliseDeUtilização.RowHeadersDefaultCellStyle.SelectionBackColor = Color.Empty
    dgvAnaliseDeUtilização.SelectionMode = DataGridViewSelectionMode.FullRowSelect
    dgvAnaliseDeUtilização.RowsDefaultCellStyle.BackColor = Color.LightGray

    ' criamos uma tabela de dados em memória
    Dim UtilizacaoDeViaturas As New DataTable

    dgvAnaliseDeUtilização.DataSource = UtilizacaoDeViaturas


    ' resposta contem a resposta do servidor
    Dim resposta As String

    ' adicionamos as colunas à DataTable
    UtilizacaoDeViaturas.Columns.Add("Data")
    UtilizacaoDeViaturas.Columns.Add("Início")
    UtilizacaoDeViaturas.Columns.Add("Fim")
    UtilizacaoDeViaturas.Columns.Add("Tempo")
    UtilizacaoDeViaturas.Columns.Add("Aluno")
    UtilizacaoDeViaturas.Columns.Add("Instrutor")
    UtilizacaoDeViaturas.Columns.Add("Km")
    UtilizacaoDeViaturas.Columns.Add("Status")

    ' questionamos o servidor e receberemos um resposta
    resposta = UtilsHttp.HttpPost("http://XXXXXXXX.com/", "SELECT * FROM agenda_real_server WHERE viatura_id='" & ViaturaSelecionada.matricula & "' AND alvara='" & VariaveisGlobais.Alvara & "'", 3274)

    ' fazemos Parse do Json
    Dim Jresultado As JArray = JArray.Parse(resposta)
    Dim resultado As List(Of JToken) = Jresultado.Children().ToList() ' ficamos com uma lista dos campos

    ' loop por todos os campos de UM RECORD e adicionamos a uma HashTable
    For Each item As JObject In resultado

        Dim hash As Hashtable = New Hashtable
        For Each propriedade As JProperty In item.Properties()
            hash.Add(propriedade.Name, propriedade.Value.ToString)
        Next

        '// Temos um Record.Alguns campos são indices.
        '// Temos de os lêr na tabela original e substituir por Strings
        '// 

        ' o aluno
        Dim IDAluno As Int16
        Dim NomeAluno As String
        IDAluno = hash.Item("aluno_id")
        NomeAluno = UtilsHttp.NomeDeAlunoPorID(IDAluno)

        'Colocamos o nome do aluno no item da Hash respectivo, substituindo o indice
        hash.Item("aluno_id") = NomeAluno

        ' O instrutor
        Dim IDInstrutor As Int16
        Dim NomeInstrutor As String
        IDInstrutor = hash.Item("instrutor_id")
        NomeInstrutor = UtilsHttp.NomeDeInstrutorPorID(IDInstrutor)

        ' colocamos o nome do instrutor no item da Hash respectivo, substituindo assim o índice
        hash.Item("instrutor_id") = NomeInstrutor


        Dim UtilizacaoDeViaturasRow As DataRow = UtilizacaoDeViaturas.NewRow

        ' agora adicionamos uma row à dataTable
        UtilizacaoDeViaturasRow.Item("Data") = hash.Item("data")
        UtilizacaoDeViaturasRow.Item("Início") = hash.Item("hora_inicio")
        UtilizacaoDeViaturasRow.Item("Fim") = hash.Item("hora_fim")
        UtilizacaoDeViaturasRow.Item("Tempo") = hash.Item("duracao")
        UtilizacaoDeViaturasRow.Item("Aluno") = hash.Item("aluno_id")
        UtilizacaoDeViaturasRow.Item("Instrutor") = hash.Item("instrutor_id")
        UtilizacaoDeViaturasRow.Item("Km") = hash.Item("km_aula")
        UtilizacaoDeViaturasRow.Item("Status") = hash.Item("status_aula_id")

        UtilizacaoDeViaturas.Rows.Add(UtilizacaoDeViaturasRow)


        dgvAnaliseDeUtilização.Refresh()
    Next

    ' Temos a Tabela construida, Informamos qual o origem dos dados e mostramos a Grid
    ' dgvAnaliseDeUtilização.DataSource = UtilizacaoDeViaturas

End Sub

这太慢了,但是太慢了以至于无法使用,特别是因为我预计有 200 个用户同时使用桌面应用程序。

【问题讨论】:

    标签: json vb.net datagridview datatable httprequest


    【解决方案1】:

    免责声明:这是从 OP 的问题中提取的。

    我发出了很多请求并解析了很多 Json 字符串,这让我很傻。

    我使用 Inner Join 构造了一个 SQL 查询,现在我拥有了我想要的所有数据,包括只有 1 个单个请求和 1 个 Json 解析的名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-04
      • 2017-07-19
      • 2010-09-08
      • 1970-01-01
      相关资源
      最近更新 更多