Ich fange gerade mit Async und Task an und mein Code wurde nicht mehr verarbeitet. Es passiert, wenn ich ein eingehendes Netzwerkpaket habe und versuche, mit der Datenbank im Pakethandler zu kommunizieren.
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");
}
}
Die Handle-Methode wird von einer asynchronen Task aufgerufen
if (_packetRepository.TryGetPacketByName(packetName, out var packet))
{
await packet.Handle(this, new ClientPacketReader(packetName, packetData));
}
else
{
Console.WriteLine("Unknown packet: " + packetName);
}
Hier ist die Methode, von der ich denke, dass sie das Problem verursacht
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-Methode von DatabaseProvider:
public DatabaseConnection GetConnection()
{
var connection = new MySqlConnection(_connectionString);
var command = connection.CreateCommand();
return new DatabaseConnection(_logFactory.GetLogger(), connection, command);
}
Konstruktor von DatabaseConnection:
public DatabaseConnection(ILogger logger, MySqlConnection connection, MySqlCommand command)
{
_logger = logger;
_connection = connection;
_command = command;
_connection.Open();
}
Wenn ich diese Zeile auskommentiere, erreicht sie die Console.WriteLine
_connection.Open();
await
. Das ist viel schwieriger zu diagnostizieren.Connection.open
kehrt nicht zurück, während versucht wird, eine Verbindung herzustellen, sondern gibt nach einer festgelegten Zeitüberschreitung endgültig auf. Sie können auch den Zeitlimitwert für das Verbindungsobjekt auf eine kleinere Zahl größer als 0 ändern und prüfen, ob eine Ausnahme vorliegt.Antworten:
Ich habe ein POC-Projekt ausgeführt, in dem 100 parallele Aufgaben sowohl mit MySql.Data 8.0.19 als auch mit MySqlConnector 0.63.2 in der .NET Core 3.1-Konsolenanwendung ausgeführt wurden. Ich erstelle, öffne und entsorge die Verbindung im Kontext jeder einzelnen Aufgabe. Beide Anbieter laufen fehlerfrei ab.
Die Besonderheiten sind, dass MySql.Data-Abfragen synchron ausgeführt werden, obwohl die Bibliothek eine Signatur für asynchrone Methoden bereitstellt, z. B. ExecuteReaderAsync () oder ExecuteScalarAsync (), während MySqlConnector wirklich asynchron ausgeführt wird .
Möglicherweise stoßen Sie auf:
quelle
Multithreading mit MySQL muss unabhängige Verbindungen verwenden. Angesichts dessen ist Multithreading keine MySQL-Frage, sondern ein Problem für die Client-Sprache, C # in Ihrer Frage.
Das heißt, erstellen Sie Ihre Threads ohne Rücksicht auf MySQL und stellen Sie dann in jedem Thread eine Verbindung her, die Abfragen ausführen muss. Es liegt auf Ihren Schultern, wenn Sie Daten zwischen den Threads übertragen müssen.
Normalerweise finde ich, dass die Optimierung von Abfragen die Versuchung beseitigt, meine Anwendungen mit mehreren Threads zu versehen.
quelle