Không có ngoại lệ bị ném khi mở MySqlConnection?


14

Tôi mới bắt đầu với async và Nhiệm vụ và mã của tôi đã ngừng xử lý. Nó xảy ra khi tôi có một gói mạng đến và tôi thử và giao tiếp với cơ sở dữ liệu bên trong trình xử lý gói.

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

Phương thức Xử lý được gọi từ một tác vụ không đồng bộ

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

Đây là phương pháp mà tôi nghĩ là gây ra vấn đề

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

Phương thức GetConnection của DatabaseProvider:

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

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

Trình xây dựng của DatabaseConnection:

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

    _connection = connection;    
    _command = command;

    _connection.Open();
}

Khi tôi nhận xét ra dòng này, nó đạt đến Console.WriteLine

_connection.Open();

3
Xin lưu ý rằng Trình kết nối / NET MySQL của Oracle (còn gọi là MySql.Data) không thực sự thực hiện bất kỳ hoạt động async nào: stackoverflow.com/a/40065501/23633 Nếu bạn muốn sử dụng các hoạt động async với MySQL, bạn nên chuyển sang nuget.org/ gói / MySqlConnector
Bradley Grainger

Có vẻ như bạn có một bế tắc trong mã của bạn. Tôi sẽ khuyên bạn nên xâm nhập vào trình gỡ lỗi Visual Studio khi điều này xảy ra và mở cửa sổ Parallel Stacks. Nếu điều này hiển thị một hoặc nhiều luồng có ngăn xếp cuộc gọi đang chặn trên Tác vụ (hoặc một số nguyên thủy đồng bộ hóa), thì bạn hy vọng sẽ có thể nói điều gì sai (hoặc chỉnh sửa thêm chi tiết vào câu hỏi để giúp chúng tôi). Nếu không có luồng nào bị chặn trên Tác vụ, thì có lẽ bạn có một Tác vụ không bao giờ được hoàn thành và không bao giờ kích hoạt mã đang awaitsử dụng. Điều đó khó chẩn đoán hơn nhiều.
Bradley Grainger

Bạn có thể thêm việc triển khai DatabaseConnection.DisposeAsync không?
eisenpony

Nếu bạn chờ đợi trong 5 phút, cuối cùng nó có ném ngoại lệ không? Connection.openkhông quay lại trong khi nó đang cố gắng kết nối, nhưng cuối cùng sẽ bỏ cuộc sau khi hết thời gian. Hoặc bạn có thể thay đổi giá trị thời gian chờ trên đối tượng kết nối thành một số nhỏ hơn 0 và xem có ngoại lệ nào không.
weichch

Câu trả lời:


1

Tôi đã chạy một dự án POC xoay 100 tác vụ song song cả với MySql.Data 8.0.19 và MySqlConnector 0.63.2 trên ứng dụng bảng điều khiển .NET Core 3.1. Tôi tạo, mở và loại bỏ kết nối vào ngữ cảnh của mọi tác vụ. Cả hai nhà cung cấp chạy đến hoàn thành mà không có lỗi.

Các đặc điểm cụ thể là các truy vấn MySql.Data chạy đồng bộ mặc dù thư viện cung cấp chữ ký phương thức async, ví dụ ExecuteReaderAsync () hoặc ExecuteScalarAsync (), trong khi MySqlConnector chạy thực sự không đồng bộ .

Bạn có thể đang chạy vào:

  • một tình huống bế tắc không liên quan cụ thể đến nhà cung cấp mysql
  • không xử lý đúng các trường hợp ngoại lệ bên trong các nhiệm vụ của bạn (bạn có thể kiểm tra ngoại lệ tổng hợp liên quan đến nhiệm vụ và cũng giám sát nhật ký db mysql)
  • bạn thực thi vẫn bị chặn (không trả về kết quả) khi bạn cho rằng nó không hoạt động, nếu bạn chạy một số lượng lớn các tác vụ song song với MySql.Data khi nó thực thi đồng bộ

0

Đa luồng với MySQL phải sử dụng các kết nối độc lập. Cho rằng, đa luồng không phải là câu hỏi của MySQL mà là vấn đề đối với ngôn ngữ máy khách, C # trong câu hỏi của bạn.

Đó là, xây dựng các chủ đề của bạn mà không cần quan tâm đến MySQL, sau đó tạo kết nối trong mỗi luồng cần thực hiện truy vấn. Nó sẽ ở trên vai bạn nếu bạn cần truyền dữ liệu giữa các luồng.

Tôi thường thấy rằng việc tối ưu hóa các truy vấn sẽ loại bỏ sự cám dỗ đối với các ứng dụng đa luồng của tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.