मुझे संदेह है कि यह समस्या है, विधि के अंत में:
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
मेरा सुझाव है कि आप मेरे कार्यक्रम को कॉपी करें और इसके साथ प्रयोग करें। सुनिश्चित करें कि आप सब कुछ समझते हैं कि क्या हो रहा है... फिर आप इसे अपने कोड पर लागू कर सकते हैं। आप इटरेटर ब्लॉक कार्यान्वयन विवरण पर मेरा लेख पढ़ना चाहेंगे। भी।