MySqlConnection खोलते समय कोई अपवाद नहीं फेंका जा रहा है?


14

मैं अभी async और टास्क के साथ शुरू कर रहा हूं और मेरे कोड ने प्रसंस्करण बंद कर दिया है। यह तब होता है जब मेरे पास एक आने वाला नेटवर्क पैकेट होता है और मैं पैकेट हैंडलर के अंदर डेटाबेस के साथ कोशिश करता हूं और संचार करता हूं।

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

हैंडल विधि को एक async कार्य से कहा जाता है

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

यहाँ विधि है जो मुझे लगता है कि इस मुद्दे का कारण है

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 के GetConnection विधि:

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

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

DatabaseConnection का निर्माता:

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

    _connection = connection;    
    _command = command;

    _connection.Open();
}

जब मैं इस लाइन पर टिप्पणी करता हूं, तो यह पहुंच जाता है Console.WriteLine

_connection.Open();

3
विदित हो कि ओरेकल का MySQL कनेक्टर / NET (उर्फ MySql.Data) वास्तव में किसी भी async ऑपरेशंस को लागू नहीं करता है: stackoverflow.com/a/40065501/23633 यदि आप MySQL के साथ async ऑपरेशंस का उपयोग करना चाहते हैं, तो आप nuget.org/ पर
ब्रैडली

ऐसा लगता है कि आपके पास अपने कोड में गतिरोध है। जब ऐसा होता है, तो मैं Visual Studio डीबगर में तोड़ने की सलाह दूंगा और समानांतर स्टैक विंडो खोलूंगा। यदि यह कॉल स्टैक के साथ एक या एक से अधिक थ्रेड्स दिखाता है जो टास्क (या कुछ सिंक्रोनाइज़ेशन आदिम) पर रोक रहे हैं, तो आप उम्मीद करते हैं कि क्या गलत हो रहा है (या हमारी मदद करने के लिए प्रश्न में अधिक विवरण संपादित करें)। यदि कोई भी कार्य टास्क पर ब्लॉक नहीं किया जाता है, तो आपके पास संभवतः एक टास्क है जो कभी पूरा नहीं हो रहा है, और उस कोड को कभी भी सक्रिय नहीं किया जा सकता है जो उस awaitपर है। इसका निदान करना बहुत कठिन है।
ब्रैडली ग्रिंगर

क्या आप DatabaseConnection.DisposeAsync के कार्यान्वयन को जोड़ सकते हैं?
आइजनपॉनी

यदि आप कहते हैं कि 5 मिनट की प्रतीक्षा करें तो क्या यह अंततः एक अपवाद है? Connection.openकनेक्ट करने का प्रयास करते समय वापस नहीं आता है, लेकिन अंत में टाइमआउट सेट के बाद छोड़ देगा। या आप कनेक्शन ऑब्जेक्ट पर टाइमआउट मान 0 से अधिक छोटी संख्या में बदल सकते हैं, और देखें कि क्या अपवाद है।
वीच

जवाबों:


1

मैंने MySql.Data 8.0.19 और MySqlConnector 0.63.2 दोनों के साथ .NET कोर 3.1 कंसोल एप्लिकेशन पर 100 समानांतर कार्यों के लिए एक POC प्रोजेक्ट चलाया। मैं हर एक कार्य के संदर्भ में कनेक्शन बनाता, खोलता और निपटाता हूं। दोनों प्रदाता त्रुटियों के बिना पूरा करने के लिए चलाते हैं।

बारीकियाँ यह हैं कि MySql.Data क्वेरी समकालिक रूप से चलती हैं, हालाँकि लाइब्रेरी Async मेथड सिग्नेचर प्रदान करती है जैसे ExecuteReaderAsync () या ExecuteScalarAsync (), जबकि MySqlConnector वास्तव में अतुल्यकालिक रूप से चलता है ।

आप इसमें शामिल हो सकते हैं:

  • एक गतिरोध की स्थिति विशेष रूप से mysql प्रदाता से संबंधित नहीं है
  • अपने कार्यों के अंदर अपवादों को ठीक से न संभालना (आप कार्य से जुड़े समग्र अपवाद का निरीक्षण कर सकते हैं और mysql db लॉग की निगरानी भी कर सकते हैं)
  • यदि आप मान लेते हैं कि यह काम नहीं कर रहा है, तो आप निष्पादन को रोक सकते हैं (रिटर्निंग रिजल्ट नहीं) यदि आप MySql.Data के साथ समानांतर कार्यों की एक उच्च संख्या चला रहे हैं क्योंकि यह तुल्यकालिक रूप से निष्पादित होता है।

0

MySQL के साथ मल्टी-थ्रेडिंग स्वतंत्र कनेक्शन का उपयोग करना चाहिए । यह देखते हुए कि, मल्टीथ्रेडिंग एक MySQL प्रश्न नहीं है, लेकिन क्लाइंट भाषा के लिए एक मुद्दा है, आपके प्रश्न में C #।

यही है, MySQL की परवाह किए बिना अपने थ्रेड्स का निर्माण करें, फिर प्रत्येक थ्रेड में एक कनेक्शन बनाएं , जिसे क्वेरी करने की आवश्यकता है। यदि आपके पास थ्रेड्स के बीच डेटा पास करने की आवश्यकता है तो यह आपके कंधों पर होगा।

मुझे आमतौर पर लगता है कि अनुकूलन संबंधी प्रश्न मेरे अनुप्रयोगों को बहु-थ्रेड के प्रलोभन को समाप्त कर देते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.