Я пытаюсь реализовать Npgsql в нашем DAL и сталкиваюсь с проблемами под большой нагрузкой. следующий пример приложения представляет собой простое представление простого запроса, который при большой нагрузке выдает исключение «команда уже выполняется». Я предполагаю, что это связано с отсутствием поддержки MARS, поэтому я также пытался каждый раз создавать соединение с помощью оператора using вокруг каждой команды, чтобы производительность стала непригодной для использования. Я проверил, что имя пользователя внесено в указатель, так что это не должно быть проблемой.
Не уверен, что я делаю не так, но мне нужен совет, как это сделать хорошо.
ОС: Docker Контейнер: Microsoft / DotNet: 2.1.301-SDK
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
namespace npgsqlTest
{
class Program
{
static async Task Main(string[] args)
{
DAL dal = new DAL();
dal.Prepare();
var tasks = dal.Users.Select(async user =>
{
Console.WriteLine(await dal.RunTest(user));
});
await Task.WhenAll(tasks);
}
}
public class DAL
{
private static string _ConnectionString;
private NpgsqlConnection _Connection;
public List<string> Users { get; set; } = new List<string>();
public DAL()
{
_ConnectionString = $"Host=192.168.1.1;Username=admin;Port=5432;Password=password;Database=BigDB;";
_Connection = new NpgsqlConnection(_ConnectionString);
_Connection.Open();
}
public void Prepare()
{
string query = "SELECT username FROM usertable;";
using (var cmd = new NpgsqlCommand(query, _Connection))
{
var reader = cmd.ExecuteReader();
using (reader)
{
while (reader.Read())
{
Users.Add(reader[0].ToString());
}
}
}
}
public async Task<string> RunTest(string user)
{
var parameters = new Dictionary<string, Object> { { "username", user } };
var query = $"SELECT name FROM usertable WHERE username = (@username);";
var reader = await QueryAsync(query, parameters);
using (reader)
{
if (reader.HasRows)
{
while (await reader.ReadAsync())
{
var name = reader["name"];
if (!(hash is DBNull))
return (string)name;
}
}
}
return String.Empty;
}
public async Task<DbDataReader> QueryAsync(string query, Dictionary<string, Object> parameters)
{
using (var cmd = new NpgsqlCommand(query, _Connection))
{
foreach (var parameter in parameters)
{
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value == null ? DBNull.Value : parameter.Value);
}
cmd.Prepare();
return await cmd.ExecuteReaderAsync();
}
}
}
}