Ho appena iniziato con asincrono e Task e il mio codice ha smesso di elaborare. Succede quando ho un pacchetto di rete in arrivo e provo a comunicare con il database all'interno del gestore pacchetti.
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");
}
}
Il metodo Handle viene chiamato da un'attività asincrona
if (_packetRepository.TryGetPacketByName(packetName, out var packet))
{
await packet.Handle(this, new ClientPacketReader(packetName, packetData));
}
else
{
Console.WriteLine("Unknown packet: " + packetName);
}
Ecco il metodo che penso stia causando il problema
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);
}
Metodo GetConnection di DatabaseProvider:
public DatabaseConnection GetConnection()
{
var connection = new MySqlConnection(_connectionString);
var command = connection.CreateCommand();
return new DatabaseConnection(_logFactory.GetLogger(), connection, command);
}
Costruttore di DatabaseConnection:
public DatabaseConnection(ILogger logger, MySqlConnection connection, MySqlCommand command)
{
_logger = logger;
_connection = connection;
_command = command;
_connection.Open();
}
Quando commento questa riga, raggiunge il Console.WriteLine
_connection.Open();
awaitin essa contenuto. È molto più difficile da diagnosticare.
Connection.opennon ritorna mentre sta tentando di connettersi, ma alla fine si arrenderà dopo un timeout impostato. In alternativa, è possibile modificare il valore di timeout sull'oggetto di connessione su un numero inferiore maggiore di 0 e vedere se esiste un'eccezione.