从webrequest填充的数据表非常慢

时间:2014-03-28 12:13:00

标签: json vb.net datagridview datatable httprequest

我一直在挖掘在 VB.net 2013 中填充数据表时极其缓慢的情况。

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

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

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

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

所以我用一个SQL语句对一个服务进行httpRequest,该服务从第三个表中返回一个包含大量字段的Json字符串。

我可以读取和解码Jsonstring,这很快,但是因为我想显示学生和课程名称,我需要每行再做两次httpRequests来联系服务器并使用StudentID获取他/她的名字然后使用CourseID获取课程名称,解码更多Json Strings。

我有一切正常工作,数据网格按预期显示值,但是每行大约需要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还有另一个类似的功能(让我们想象一下我正在使用的那个例子的课程名称。

我从主代码调用此函数来填充数据表,并显示datagridview:

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位用户同时使用桌面应用程序。

1 个答案:

答案 0 :(得分:0)

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

我通过解雇somany请求并解析如此多的Json字符串而感到狡猾。

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