Не возникает ли исключение при открытии MySqlConnection? - PullRequest
14 голосов
/ 07 апреля 2020

Я только начинаю с asyn c и Task, и мой код прекратил обработку Это происходит, когда у меня есть входящий сетевой пакет, и я пытаюсь связаться с базой данных внутри обработчика пакетов.

public class ClientConnectedPacket : IClientPacket
{
    private readonly EntityFactory _entityFactory;

    public ClientConnectedPacket(EntityFactory entityFactory)
    {
        _entityFactory= entityFactory;
    }

    public async Task Handle(NetworkClient client, ClientPacketReader reader)
    {
        client.Entity = await _entityFactory.CreateInstanceAsync( reader.GetValueByKey("unique_device_id"));

        // this Console.WriteLine never gets reached
        Console.WriteLine($"Client [{reader.GetValueByKey("unique_device_id")}] has connected");
    }
}

Метод Handle вызывается из асинхронной c задачи

if (_packetRepository.TryGetPacketByName(packetName, out var packet))
{
    await packet.Handle(this, new ClientPacketReader(packetName, packetData));
}
else
{
    Console.WriteLine("Unknown packet: " + packetName);
}

Вот метод, который, я думаю, вызывает проблему

public async Task<Entity> CreateInstanceAsync(string uniqueId)
{
    await using (var dbConnection = _databaseProvider.GetConnection())
    { 
        dbConnection.SetQuery("SELECT COUNT(NULL) FROM `entities` WHERE `unique_id` = @uniqueId");
        dbConnection.AddParameter("uniqueId", uniqueId);

        var row = await dbConnection.ExecuteRowAsync();

        if (row != null)
        {
            return new Entity(uniqueId, false);
        }
    }

    return new Entity(uniqueId,true);
}

Метод GetConnection DatabaseProvider:

public DatabaseConnection GetConnection()
{
    var connection = new MySqlConnection(_connectionString);
    var command = connection.CreateCommand();

    return new DatabaseConnection(_logFactory.GetLogger(), connection, command);
}

Конструктор DatabaseConnection:

public DatabaseConnection(ILogger logger, MySqlConnection connection, MySqlCommand command)
{
    _logger = logger;

    _connection = connection;    
    _command = command;

    _connection.Open();
}

Когда я комментирую из этой линии он достигает Console.WriteLine

_connection.Open();

Ответы [ 2 ]

1 голос
/ 17 апреля 2020

Я запустил проект PO C, включающий 100 параллельных задач с MySql .Data 8.0.19 и MySqlConnector 0.63.2 на. NET Консольное приложение Core 3.1. Я создаю, открываю и размещаю соединение в контексте каждой отдельной задачи. Оба поставщика работают до завершения без ошибок.

Особенности: MySql .Данные запросы выполняются синхронно , хотя библиотека предоставляет асинхронную c сигнатуру методов, например, ExecuteReaderAsyn c () или ExecuteScalarAsyn c (), в то время как MySqlConnector работает действительно асинхронно .

Возможно, вы столкнулись с:

  • тупиковой ситуацией, не связанной конкретно с mysql провайдером
  • , который неправильно обрабатывает исключения внутри ваших задач (вы можете проверить задача связана с агрегатным исключением, а также отслеживает mysql журналы дБ)
  • ваше выполнение будет по-прежнему заблокировано (не возвращая результат), если вы предполагаете, что оно не работает, если вы выполняете большое количество параллельных задач с MySql .Данные в синхронном режиме
0 голосов
/ 12 апреля 2020

Многопоточность с MySQL должна использовать независимые соединения. Учитывая это, многопоточность - это не вопрос MySQL, а проблема для языка клиента, C# в вашем вопросе.

То есть создавайте ваши потоки без учета MySQL, затем создать соединение в каждом потоке, который должен делать запросы. Это будет на ваших плечах, если вам нужно будет передавать данные между потоками.

Я обычно нахожу, что оптимизация запросов устраняет соблазн многопоточности моих приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...