Производительность Npgsql - PullRequest
       27

Производительность Npgsql

0 голосов
/ 02 сентября 2018

Я пытаюсь реализовать 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();
        }
    }
}
}
...