MySqlConnection açılırken herhangi bir istisna yapılmıyor mu?


14

Sadece zaman uyumsuzluk ve Görev ile başlıyorum ve kodum durdu. Gelen bir ağ paketim olduğunda ve paket işleyicisinin içindeki veritabanıyla iletişim kurmaya çalıştığımda olur.

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");
    }
}

Tanıtıcı yöntemi, zaman uyumsuz bir görevden çağrılır

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

İşte soruna neden olduğunu düşündüğüm yöntem

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);
}

DatabaseProvider'ın GetConnection yöntemi:

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

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

DatabaseConnection yapıcısı:

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

    _connection = connection;    
    _command = command;

    _connection.Open();
}

Bu satıra yorum yaptığımda, Console.WriteLine

_connection.Open();

3
Oracle'ın MySQL Bağlayıcısı / NET'inin (diğer bir deyişle MySql.Data) aslında herhangi bir zaman uyumsuz işlem gerçekleştirmediğini unutmayın: stackoverflow.com/a/40065501/23633 MySQL ile zaman uyumsuz işlemleri kullanmak istiyorsanız, nuget.org/ paketleri / MySqlConnector
Bradley Grainger

Kodunuzda bir kilitlenme var gibi görünüyor. Bu olduğunda Visual Studio hata ayıklayıcısına girmeyi ve Paralel Yığınlar penceresini açmanızı öneririm. Bu, bir Görevde (veya bazı senkronizasyon ilkelinde) engellenen çağrı yığınlarına sahip bir veya daha fazla iş parçacığı gösteriyorsa, neyin yanlış gittiğini söyleyebilir (veya bize yardımcı olmak için soruya daha fazla ayrıntı düzenleyebilirsiniz). Bir Görevde hiçbir iş parçacığı engellenmezse, büyük olasılıkla hiçbir zaman tamamlanmayan ve awaitüzerinde çalışan kodu asla etkinleştirmeyen bir Göreviniz vardır . Teşhis etmek çok daha zor.
Bradley Grainger

DatabaseConnection.DisposeAsync uygulamasını ekleyebilir misiniz?
eisenpony

5 dakika beklerseniz sonunda bir istisna atar mı? Connection.openbağlanmaya çalışırken dönmez, ancak sonunda bir zaman aşımı ayarından sonra vazgeçer. Veya bağlantı nesnesindeki zaman aşımı değerini 0'dan küçük bir sayıya dönüştürebilir ve istisna olup olmadığını görebilirsiniz.
weichch

Yanıtlar:


1

.NET Core 3.1 konsol uygulamasında hem MySql.Data 8.0.19 hem de MySqlConnector 0.63.2 ile 100 paralel görev döndüren bir POC projesi çalıştırdım. Bağlantıyı her bir görevin bağlamında oluşturur, açar ve atarım. Her iki sağlayıcı da hatasız olarak tamamlanır.

Özellikler, MySql.Data sorgularının eşzamanlı olarak çalışmasına rağmen, kitaplık eşzamansız yöntemler imzası örneğin ExecuteReaderAsync () veya ExecuteScalarAsync () sağlarken, MySqlConnector gerçekten eşzamansız olarak çalışır .

Şunlarla karşılaşıyor olabilirsiniz:

  • mysql sağlayıcısı ile ilgili olmayan bir kilitlenme durumu
  • görevlerinizdeki istisnaları düzgün işlememe (görevle ilişkili toplu istisnaları inceleyebilir ve ayrıca mysql db günlüklerini izleyebilirsiniz)
  • senkronize olarak yürütülürken MySql.Data ile çok sayıda paralel görev çalıştırıyorsanız, çalışmadığınızı varsaydığınızda yürütme yine de engellenir (sonuç döndürmüyor)

0

Çoklu-işlem MySQL ile zorundadır bağımsız bağlantıları kullanın. Bu nedenle, çoklu iş parçacığı bir MySQL sorusu değil, sorunuzdaki istemci dili C # için bir sorundur.

Yani, MySQL ile ilgilenmeden iş parçacıklarınızı oluşturun , ardından her iş parçacığında sorgulama yapmak için bir bağlantı oluşturun. İş parçacıkları arasında veri aktarmanız gerekiyorsa, omuzlarınızda olacaktır.

Genellikle, sorguları optimize etmenin uygulamalarımı çok iş parçacıklı hale getirme eğilimini ortadan kaldırdığını görürüm.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.