Saya baru mulai dengan async dan Task dan kode saya sudah berhenti diproses. Itu terjadi ketika saya memiliki paket jaringan masuk dan saya mencoba dan berkomunikasi dengan database di dalam pengendali paket.
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");
}
}
Metode Handle dipanggil dari tugas async
if (_packetRepository.TryGetPacketByName(packetName, out var packet))
{
await packet.Handle(this, new ClientPacketReader(packetName, packetData));
}
else
{
Console.WriteLine("Unknown packet: " + packetName);
}
Inilah metode yang menurut saya menyebabkan masalah
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);
}
Metode GetConnection dari DatabaseProvider:
public DatabaseConnection GetConnection()
{
var connection = new MySqlConnection(_connectionString);
var command = connection.CreateCommand();
return new DatabaseConnection(_logFactory.GetLogger(), connection, command);
}
Konstruktor DatabaseConnection:
public DatabaseConnection(ILogger logger, MySqlConnection connection, MySqlCommand command)
{
_logger = logger;
_connection = connection;
_command = command;
_connection.Open();
}
Ketika saya mengomentari baris ini, ini mencapai Console.WriteLine
_connection.Open();
await
di dalamnya. Itu jauh lebih sulit untuk didiagnosis.Connection.open
tidak kembali ketika sedang mencoba untuk terhubung, tetapi akhirnya akan menyerah setelah batas waktu yang ditentukan. Atau Anda dapat mengubah nilai batas waktu pada objek koneksi ke angka yang lebih kecil lebih besar dari 0, dan melihat apakah ada pengecualian.Jawaban:
Saya menjalankan proyek POC yang memutar 100 tugas paralel baik dengan MySql.Data 8.0.19 dan MySqlConnector 0.63.2 pada aplikasi konsol .NET Core 3.1. Saya membuat, membuka dan membuang koneksi ke dalam konteks setiap tugas. Kedua penyedia berjalan hingga selesai tanpa kesalahan.
Secara spesifik adalah bahwa pertanyaan MySql.Data berjalan secara sinkron meskipun pustaka menyediakan tanda tangan metode async misalnya ExecuteReaderAsync () atau ExecuteScalarAsync (), sementara MySqlConnector berjalan benar-benar tidak sinkron .
Anda mungkin mengalami:
sumber
Multi-threading dengan MySQL harus menggunakan koneksi independen. Karena itu, multithreading bukan pertanyaan MySQL tetapi masalah untuk bahasa klien, C # dalam pertanyaan Anda.
Artinya, buat utas Anda tanpa memperhatikan MySQL, lalu buat koneksi di setiap utas yang perlu dilakukan kueri. Ini akan berada di pundak Anda jika Anda harus melewatkan data di antara utas.
Saya biasanya menemukan bahwa kueri pengoptimalan menghilangkan godaan untuk multi-thread aplikasi saya.
sumber