Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

पहले से ही एक खुला DataReader है ... भले ही वह नहीं है

मुझे संदेह है कि यह समस्या है, विधि के अंत में:

this.connectionPool.Putback(sqlConnection);

आप केवल ले रहे हैं इटरेटर से दो तत्व - ताकि आप कभी भी while को पूरा न करें लूप जब तक कि पाठक से वास्तव में केवल एक ही मान वापस न आए। अब आप LINQ का उपयोग कर रहे हैं, जो स्वचालित रूप से Dispose() . को कॉल करेगा इटरेटर पर, इसलिए आपका using कथन अभी भी पाठक का निपटान करेगा - लेकिन आप कनेक्शन को वापस पूल में नहीं डाल रहे हैं। अगर आप finally . में ऐसा करते हैं ब्लॉक करें, मुझे लगता है कि आप ठीक हो जाएंगे:

var sqlConnection = this.connectionPool.Take();
try
{
    // Other stuff here...

    using (var reader = this.selectWithSourceVectorCommand.ExecuteReader())
    {
        while (reader.Read())
        {
            yield return ReaderToVectorTransition(reader);
        }
    }
}
finally
{
    this.connectionPool.Putback(sqlConnection);
}

या आदर्श रूप से, यदि आपका कनेक्शन पूल आपका स्वयं का कार्यान्वयन है, तो Take . बनाएं कुछ ऐसा लौटाएं जो IDisposable लागू करता हो और पूरा होने पर कनेक्शन को वापस पूल में लौटा देता है।

यहां क्या हो रहा है, यह दिखाने के लिए एक छोटा लेकिन पूरा कार्यक्रम है, जिसमें कोई वास्तविक डेटाबेस शामिल नहीं है:

using System;
using System.Collections.Generic;
using System.Linq;

class DummyReader : IDisposable
{
    private readonly int limit;
    private int count = -1;
    public int Count { get { return count; } }

    public DummyReader(int limit)
    {
        this.limit = limit;
    }

    public bool Read()
    {
        count++;
        return count < limit;
    }

    public void Dispose()
    {
        Console.WriteLine("DummyReader.Dispose()");
    }
}

class Test
{    
    static IEnumerable<int> FindValues(int valuesInReader)
    {
        Console.WriteLine("Take from the pool");

        using (var reader = new DummyReader(valuesInReader))
        {
            while (reader.Read())
            {
                yield return reader.Count;
            }
        }
        Console.WriteLine("Put back in the pool");
    }

    static void Main()
    {
        var data = FindValues(2).Take(2).ToArray();
        Console.WriteLine(string.Join(",", data));
    }
}

जैसा लिखा है - पाठक के साथ स्थिति को मॉडलिंग करना केवल दो मान ढूंढ रहा है - आउटपुट है:

Take from the pool
DummyReader.Dispose()
0,1

ध्यान दें कि पाठक का निपटारा किया जाता है, लेकिन हम पूल से कुछ भी वापस करने के रूप में कभी भी प्राप्त नहीं करते हैं। अगर आप Main बदलते हैं उस स्थिति को मॉडल करने के लिए जहां पाठक के पास केवल एक मान होता है, जैसे:

var data = FindValues(1).Take(2).ToArray();

फिर हम while . के माध्यम से सभी तरह से प्राप्त करते हैं लूप, इसलिए आउटपुट बदल जाता है:

Take from the pool
DummyReader.Dispose()
Put back in the pool
0

मेरा सुझाव है कि आप मेरे कार्यक्रम को कॉपी करें और इसके साथ प्रयोग करें। सुनिश्चित करें कि आप सब कुछ समझते हैं कि क्या हो रहा है... फिर आप इसे अपने कोड पर लागू कर सकते हैं। आप इटरेटर ब्लॉक कार्यान्वयन विवरण पर मेरा लेख पढ़ना चाहेंगे। भी।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL सिंटैक्स त्रुटि सही सिंटैक्स 'desc' के पास उपयोग करने के लिए

  2. Mysql खोजों में एस्ट्रोफ़ेस को अनदेखा करना

  3. mySQL से पहले X शब्द (सिर्फ अक्षर नहीं) खींचे

  4. MySQL - एक INSERT कथन के अंदर एक स्ट्रिंग मान को DATETIME प्रारूप में कैसे पार्स करें?

  5. डेटाबेस में आईपी स्टोर करने का सबसे अच्छा तरीका?