Как обрабатывать параллельное выполнение C # для подключения к базе данных - PullRequest
2 голосов
/ 07 марта 2012

У меня есть следующий код, который будет запускать запрос для каждой базы данных в SQL SERVER 2008R2,

public DataTable GetResultsOfAllDB(string query)
        {
            SqlConnection con = new SqlConnection(_ConnectionString);
            string locleQuery = "select name from [master].sys.sysdatabases";
            DataTable dtResult = new DataTable("Result");
            SqlCommand cmdData = new SqlCommand(locleQuery, con);
            cmdData.CommandTimeout = 0;

            SqlDataAdapter adapter = new SqlDataAdapter(cmdData);
            DataTable dtDataBases = new DataTable("DataBase");
            adapter.Fill(dtDataBases);

            // This is implemented for sequential           
            foreach (DataRow drDB in dtDataBases.Rows)
            {
                locleQuery = " Use [" + Convert.ToString(drDB[0]) + "]; " + query;
                cmdData = new SqlCommand(locleQuery, con);
                adapter = new SqlDataAdapter(cmdData);
                DataTable dtTemp = new DataTable();
                adapter.Fill(dtTemp);
                dtResult.Merge(dtTemp);
            }

            //Parallel Implementation
            Parallel.ForEach(dtDataBases.AsEnumerable(), drDB =>
                {
                    locleQuery = " Use [" + Convert.ToString(drDB[0]) + "]; " + query;
                    con = new SqlConnection(_ConnectionString);
                    cmdData = new SqlCommand(locleQuery, con);
                    cmdData.CommandTimeout = 0;
                    adapter = new SqlDataAdapter(cmdData);
                    DataTable dtTemp = new DataTable();
                    adapter.Fill(dtTemp);
                    dtResult.Merge(dtTemp);
                }
            );

            return dtResult;

        }

Теперь проблема в том, что когда я использую второй цикл, то есть цикл Parallel ForEach, он выдает мне разные ошибки в строке adapter.Fill(dtTemp);, как показано ниже,

Да, конечно, это ожидаемые ошибки.

  1. Соединение закрыто
  2. Соединение открывается,
  3. Считыватель данных закрыт
  4. читатель подключается .. Blha Blha ... Все ошибки, связанные с подключением.

Примечание: иногда это работает как шарм, я имею в виду без ошибок.

И, безусловно, первый цикл, т.е. последовательный цикл foreach работает нормально, но производительность не так хороша, как я влюбился в него:)

Теперь мой вопрос: если я хочу использовать цикл parallel foreach для того же, то как мне это сделать? Есть ли какая-нибудь косметика, которая поможет петле Parallel Foreach хорошо выглядеть;)

Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 07 марта 2012

Соединение с базой данных может выполнять только один запрос за раз, поэтому, когда поток пытается выполнить запрос, когда соединение занято, вы получаете сообщение об ошибке.Если вы хотите выполнять запросы параллельно, каждому потоку необходимо свое собственное соединение с базой данных.

2 голосов
/ 14 января 2013

Хотя вы создаете новый объект SqlConnection для каждой итерации, все объекты используют одно и то же физическое соединение с базой данных. Это из-за пула соединений, используемого .NET Framework. В вашем случае вам нужно вручную настроить поведение пула соединений. Например, вы можете отключить пул соединений; это будет иметь последствия для производительности. Подробнее о пуле подключений на MSDN .

...