Я пытаюсь прочитать данные из базы данных и сгенерировать XML из нее. Для этого у меня есть 5 SQL запросов и некоторый код для генерации XML, все в одном Parallel.Foreach
l oop.
Это выглядит так:
List<int> contractIDs = new List<int>();
// ... some code to get all IDs
Parallel.ForEach(contractIDs, new ParallelOptions { MaxDegreeOfParallelism = 8 }, (id) =>
{
SqlConnection connection = new SqlConnection("connectionString");
connection.Open();
SqlCommand query1 = new SqlCommand(@"some query");
SqlCommand query2 = new SqlCommand(@"some query");
SqlCommand query3 = new SqlCommand(@"some query");
SqlCommand query4 = new SqlCommand(@"some query");
SqlCommand query5 = new SqlCommand(@"some query");
// ... some code for XML generation
using (SqlDataReader contractTypeReader = query1.ExecuteReader())
{
if (contractTypeReader.HasRows)
{
while (contractTypeReader.Read())
{
// .... read from database and generate XML
}
}
}
// handle the other four queries the same way
// ... save xml
connection.Close();
}
Если я запускаю его с MaxDegreeOfParallelism = 1
, он работает, но если я использую более одного потока, он в какой-то момент будет случайным образом обрабатывать sh либо с синтаксической ошибкой, либо с незакрытой цитатой.
Поскольку единственное, что изменяется в запросах, это идентификатор, который является целым числом, он всегда дает сбой в другой точке и работает в одном потоке. Я предполагаю, что должна быть проблема с параллельным сервером l oop или SQL.
Edit
, хотя я не думаю, проблема в неправильном sql запросе ниже, это один из запросов и соответствующее сообщение об ошибке.
SqlCommand contractValues = new SqlCommand(@"select cv.value, s.form_name, cp.description, test.value as pv_value
from dbo.contract_values cv
join dbo.structures s on cv.structures_id = s.id
join dbo.components c on s.component_id = c.id
join dbo.component cp on cp.id = c.component_id
left join (select property_values.value, property_values.structure_id, cp.*
from dbo.property_values
join component_properties cp on cp.id = property_values.component_properties_id) test on test.structure_id = s.id and test.name = 'label'
where cv.contracts_id = " + id + " and cp.name != 'combobox'", connection);
$exception {"Unclosed quotation mark after the character string 'combobox'.\r\nIncorrect syntax near 'combobox'."} System.Data.SqlClient.SqlException
Я знаю, что это не особо безопасный способ обработки запроса с объединенной строкой но в моем случае угрозы безопасности нет.
Если я возьму текст команды из запроса, выдавшего ошибку, и запустлю его вручную в SSMS, то, похоже, с этим проблем не будет. Но так как я впервые пишу многопоточный код в c#, я не уверен, как отладить проблему.