C# 打开MySqlConnection时没有引发异常?

C# 打开MySqlConnection时没有引发异常?,c#,mysql,C#,Mysql,我刚开始使用async和Task,我的代码已停止处理。当我有一个传入的网络数据包,并且我试图在数据包处理程序中与数据库通信时,就会发生这种情况 public class ClientConnectedPacket : IClientPacket { private readonly EntityFactory _entityFactory; public ClientConnectedPacket(EntityFactory entityFactory) {

我刚开始使用async和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");
    }
}
句柄方法从异步任务调用

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);
}
数据库连接的构造函数:

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

    _connection = connection;    
    _command = command;

    _connection.Open();
}
当我注释掉这一行时,它到达
控制台。WriteLine

_connection.Open();

MySQL的多线程必须使用独立连接。考虑到这一点,多线程不是MySQL的问题,而是客户机语言C#的问题

也就是说,在不考虑MySQL的情况下构建线程,然后在每个需要执行查询的线程中创建一个连接。如果您需要在线程之间传递数据,它将由您承担


我通常会发现,优化查询可以消除多线程应用程序的诱惑。

我在.NET Core 3.1控制台应用程序上运行了一个POC项目,使用MySql.Data 8.0.19和MySqlConnector 0.63.2实现了100个并行任务。我在每个任务的上下文中创建、打开和处理连接。两个提供程序都运行到完成,没有错误

具体来说,MySql.Data查询同步运行,尽管库提供了异步方法签名,例如ExecuteReaderAsync()或ExecuteScalarAsync(),而MySqlConnector真正异步运行

您可能会遇到:

  • 与mysql提供程序无关的死锁情况
  • 未正确处理任务内的异常(您可以检查与任务相关的聚合异常,还可以监视mysql db日志)
  • 如果使用MySql.Data同步执行大量并行任务,则假设它不工作时,执行仍然会被阻止(不返回结果)

请注意,Oracle的MySQL Connector/NET(又名MySQL.Data)实际上并没有实现任何异步操作:如果您想对MySQL使用异步操作,您应该切换到它,听起来您的代码中有死锁。我建议在发生这种情况时进入VisualStudio调试器并打开“并行堆栈”窗口。如果这显示了一个或多个线程的调用堆栈阻塞了一个任务(或某些同步原语),那么您希望能够知道出了什么问题(或编辑问题中的更多细节以帮助我们)。如果任务中没有线程被阻塞,那么您可能有一个任务永远不会完成,也永远不会激活等待它的代码。这更难诊断。你能添加DatabaseConnection.DisposeAsync的实现吗?如果你等5分钟,它最终会抛出异常吗<代码>连接。open在尝试连接时不会返回,但在设置超时后将最终放弃。或者,您可以将连接对象上的超时值更改为大于0的较小数字,然后查看是否存在异常。
_connection.Open();