并行foreach循环中的mysql连接问题

时间:2017-11-24 17:05:00

标签: mysql vb.net parallel-processing

我有两节课。一个类保存数据库信息,而另一个类处理与数据库之间的信息;这个类也可以访问服务器,但这对此无关紧要。

我的问题是,当我尝试并行使用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

0 个答案:

没有答案