【发布时间】: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