我有两节课。一个类保存数据库信息,而另一个类处理与数据库之间的信息;这个类也可以访问服务器,但这对此无关紧要。
我的问题是,当我尝试并行使用foreach循环时,程序会随机生成ssl连接错误。在服务器阻止我的IP地址之前,错误会一直存在。如果我保持循环不并行,我没有错误。不幸的是,我需要程序运行得更快。请注意,这是一个独立的应用程序,因此无需担心sql注入或任何其他内容。
如何并行创建此功能?
Imports Newtonsoft.Json
' This class handles searching and extracting relevant data to the database
Public Class RiotDataExtractor
Private rda As New RiotDataAdapter
Private rm As New RemoteManager
Private summonerQueryCount As Integer = -5
Private strInsertQuery As String = ""
Private strUpdateQuery As String = ""
Public Sub New()
Try
dataExtraction()
Catch ex As Exception
Console.WriteLine(ex.Message + " in RiotDataExtractor/new.")
End Try
End Sub
' Gathers the list of summoners, |summonerQueryCount| at a time and send them to search their match history
Private Sub dataExtraction()
Try
Dim summoner_count As Integer = rm.returnDBQueryAsDataTable("SELECT COUNT(*) FROM summoner_data;").Rows(0).Item(0)
For i As Integer = (summoner_count - 1) To 0 Step summonerQueryCount
Dim dt As DataTable = rm.returnDBQueryAsDataTable("SELECT * FROM summoner_data limit " & (i + summonerQueryCount).ToString & ", " & (-summonerQueryCount).ToString() & ";")
If dt.Rows.Count = 0 Then
Exit For
End If
For j As Integer = 0 To dt.Rows.Count - 1
searchMatchHistoryForSummoner(dt.Rows(j).Item(3).ToString(), dt.Rows(j).Item(0).ToString())
Next
Next
Catch ex As Exception
Console.WriteLine(ex.Message + " in RiotDataExtractor/dataExtraction.")
End Try
End Sub
' Find the match history for a player from the database
Private Sub searchMatchHistoryForSummoner(ByVal strRegion As String, ByVal strAccountId As String)
Try
Dim convertedId As String = JsonConvert.DeserializeObject(Of LeagueSummonerData)(rda.convertID(strRegion, strAccountId)).accountId.ToString()
Dim matchHistory As LeagueMatchManager = JsonConvert.DeserializeObject(Of LeagueMatchManager)(rda.returnMatchHistoryForDataExtractor(strRegion, convertedId))
Parallel.ForEach(matchHistory.matches, Function(match As LeagueMatchList)
searchMatchData(match.gameId.ToString(), strRegion)
Return Nothing
End Function)
Catch ex As Exception
Console.WriteLine(ex.Message + " in RiotDataExtractor/searchMatchHistory.")
End Try
End Sub
' Search for match data from an ID
Private Sub searchMatchData(ByVal matchId As String, ByVal strRegion As String)
Try
Dim league_match As LeagueMatch = JsonConvert.DeserializeObject(Of LeagueMatch)(rda.returnLeagueMatch(matchId, strRegion))
'Parallel.ForEach(league_match.participantIdentities, Function(player As LeagueParticipantIdentity)
' searchPlayerInformation(player.player.summonerId.ToString(), strRegion)
' Return Nothing
' End Function)
For Each player In league_match.participantIdentities
searchPlayerInformation(player.player.summonerId.ToString(), strRegion)
Next
Catch ex As Exception
Console.WriteLine(ex.Message + " in RiotDataExtractor/searchMatchData.")
End Try
End Sub
' Uses summoner id from a match to gather all relevant information and insert into database
Private Sub searchPlayerInformation(ByVal summonerId As String, ByVal strRegion As String)
Debug.WriteLine(summonerId & "||" & strRegion)
If summonerId > 0 Then
Try
Dim summonerData As LeagueSummonerData = JsonConvert.DeserializeObject(Of LeagueSummonerData)(rda.returnLeagueSummoner(strRegion, summonerId))
Dim dt As DataTable = rm.returnDBQueryAsDataTable("SELECT * FROM summoner_data WHERE account_id = " + summonerData.id.ToString() + ";")
If dt.Rows.Count > 1 Then
rm.executeDBQuery("DELETE * FROM summoner_data WHERE account_id = ")
End If
If dt.Rows.Count = 1 Then
rm.executeDBQuery("UPDATE summoner_data SET summoner_name = '" + summonerData.name + "', summoner_level = " + summonerData.summonerLevel.ToString() + " WHERE account_id = " + summonerData.id.ToString() + " AND region = '" + strRegion + "';")
ElseIf (dt.Rows.Count = 0) Then
rm.executeDBQuery("INSERT INTO summoner_data (account_id, summoner_name, summoner_level, region) VALUES (" + summonerData.id.ToString() + ", '" + summonerData.name + "', " + summonerData.summonerLevel.ToString() + ", '" + strRegion + "');")
End If
Catch ex As Exception
Console.WriteLine(ex.Message + " in RiotDataExtractor/searchPlayerInformation.")
End Try
End If
End Sub
End Class
********************************************************
This is the class where I access the remote database.
Public Function returnDBQueryAsDataTable(ByVal strQuery As String) As DataTable
Dim dtLogin As DataTable = New DataTable()
Dim conn = New MySqlConnection(String.Format("server={0}; user id={1}; password={2}; database={3}; pooling=false", summoner_spell, item_text, map_name, champ))
conn.Open()
Try
Using conn
Using cmd = New MySqlCommand(strQuery, conn)
Dim daLogin = New MySqlDataAdapter(cmd)
daLogin.Fill(dtLogin)
End Using
End Using
Catch ex As Exception
System.Diagnostics.Debug.WriteLine("Query failed: " + strQuery)
Finally
conn.Close()
End Try
Return dtLogin
End Function
Public Sub executeDBQuery(ByVal strQuery As String)
Try
Dim conn = New MySqlConnection(String.Format("server={0}; user id={1}; password={2}; database={3}; pooling=false", summoner_spell, item_text, map_name, champ))
conn.Open()
Using conn
Using cmd = New MySqlCommand(strQuery, conn)
cmd.ExecuteNonQuery()
End Using
End Using
conn.Close()
Debug.WriteLine("Query succeeded: " + strQuery)
Catch ex As Exception
Debug.WriteLine("Query failed: " + strQuery + "//" + ex.Message)
End Try
End Sub
End Class