2017-02-14 20 views
0

Я пытаюсь увеличить пропускную способность базы данных PostgreSQL, и один огромный скачок производительности можно получить, перейдя из пулов потоков в асинхронные запросы. Вот вариант кода, который будет выполнять указанный запрос async:Количество параллельных соединений с Npgsql и async

using (var conn = new NpgsqlConnection(connStr)) { 
    await conn.OpenAsync(); 
    var id = await conn.ExecuteScalarAsync<long>(
     "my_proc", 
     param_obj, 
     commandType: CommandType.StoredProcedure, 
     commandTimeout: 0 
    ); 
    return id; 
} 

Ранее при использовании пулов потоков, я мог установить максимальное количество открытых соединений в любой момент времени, просто установив количество потоков (и если Я превысил MaxPoolSize, я бы видел, как израсходованы исчерпаны пулы/тайм-аут, как и ожидалось). В этом случае, не будет ли количество соединений взорваться довольно быстро? Возможно, есть более канонический способ сделать это, о котором я не знаю.

ответ

1

Тот факт, что ваш код асинхронен, сам по себе не меняет работу пула соединений, и он (опять же сам по себе) не исчерпывает пул быстрее. В тот момент, когда OpenAsync() завершает (асинхронно), соединение было выделено из пула в ваш код и будет считаться занятым до его размещения. Это не принципиально отличается от того, как все работает в синхронном коде; единственная разница заключается в том, что в версии синхронизации есть блокировка потока для всех операций ввода-вывода, но не в асинхронной версии.

Теперь кажется, что в вашей предыдущей версии синхронизации вы одновременно контролировали количество подключений, установив количество потоков, выполняющих код базы данных. Поскольку с асинхронным потоком получается, как только происходит ввод-вывод, это явно не актуально. Вместо этого вы можете просто контролировать количество раз, когда вы (одновременно) используете свой код выше. Например, вы можете запустить свой код для 100 значений параметров, а затем использовать Task.WhenAny(), чтобы дождаться завершения любой из этих операций. Когда это произойдет, вы можете выполнить другую задачу (с новым значением параметра) и так далее.