2016-05-24 3 views
1

У меня есть процесс, который передает результаты из сотни запросов в 5 разных базах данных в файл на диске с использованием шаблона производителя-потребителя. Все запросы и подключения работают при последовательном запуске (или если я постоянно повторяю их параллельно), однако при их потоковой передаче некоторые из соединений не работают.Ошибка подключения к PostgreSQL при многопоточности. C#

В настоящее время я просто добавляю неудачные попытки к неудачной коллекции, а затем повторяю их рекурсивно, чтобы они, в конце концов, закончили, но много времени тратится впустую с этими неудачными подключениями.

Вот соответствующий код, я использую:

public void executeNodes(List<Node> nodeList, BlockingCollection<Dictionary<string, object>> producer, int retryAttempts) { 
     BlockingCollection<Node> retryNodes = new BlockingCollection<Node>(); 
     Parallel.ForEach(nodeList, new ParallelOptions() { MaxDegreeOfParallelism = 10 }, node => { 
      NpgsqlConnection conn = new NpgsqlConnection(node.ConnectionString); 
      try { 
       conn.Open(); 
       NpgsqlCommand npgQuery = new NpgsqlCommand(node.Query, conn); 
       NpgsqlDataReader reader = npgQuery.ExecuteReader(); 
       while (reader.Read()) { 
        Dictionary<string, object> row = new Dictionary<string, object>(); 
        for (int i = 0; i < reader.FieldCount; i++) { 
         row[reader.GetName(i)] = reader.GetValue(i); 
        } 
        producer.Add(row); 
       } 
       conn.Close(); 
       //Console.WriteLine("Success"); 
      } catch (Exception e) { 
       //Console.WriteLine("Failed"); 
       retryNodes.Add(node); 
      } 
     }); 
     if (retryNodes.Count == 0 || retryAttempts == 0) producer.CompleteAdding(); 
     else executeNodes(retryNodes.ToList<Node>(), producer, retryAttempts - 1); 
    } 

Если узел просто:

public class Node { 
    public string ConnectionString; 
    public string Query; 

    public Node(string connectionString, string query) { 
     ConnectionString = connectionString; 
     Query = query; 
    } 
} 

Этот процесс будет успешно работать и правильно, но это раздражает, что я получаю соединение неудачи. Любая помощь будет принята с благодарностью.

Примечание:

Я попытался добавить:

ServicePointManager.DefaultConnectionLimit = 20; 

Я пытался добавить реестр записи specified in this page

Неудача соединения не являются следствием пула соединений были достигнут.

Ошибки я вижу, являются:

"Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." 
+0

После того, сколько соединений вы начинаете видеть проблемы? Вы уверены, что пул используется и что у вас не хватает эфемерных портов? – 9Rune5

+0

Таким образом, я ограничил количество узлов до 10, при этом одна из них была в одной базе данных, а остальные 9 - другой. Каждый раз, когда я запускаю первое соединение, всегда получается успех, но тогда все остальные кажутся почти случайными, если они успешны или нет. Иногда 6/10 иногда работают только с первой работой. Вы знаете, как я могу проверить количество доступных эфемерных портов? Редактировать, просто побежал снова, и только первый провалился, а остальное удалось, поэтому предыдущее утверждение было частично ложным. –

+0

Число портов TCP в тысячах. Если у вас возникли проблемы после нескольких сеансов связи, забудьте мой комментарий. – 9Rune5

ответ

1

Так что моя проблема была с пулом подключений. Как только я установил значение false в строке соединения, все сработало нормально.

Смежные вопросы