2012-01-25 22 views
6

एक चल रहे पाठक को रोकना संभव है?क्या मैं पढ़ने के दौरान डेटा रीडर को बाधित कर सकता हूं?

परिदृश्य: मैं सेट 100000 डेटा की एक तालिका

CREATE TABLE stock (
uid bigint NOT NULL, 
name text, 
quantity integer, 
x bytea, 
y bytea 
); 

और एक सांत्वना आवेदन (.NET 4.0, Npgsql 2.0.11.0/2.0.11.92) डेटा पढ़ने

conn = new NpgsqlConnection("Server=localhost;Database=postgres;User id=postgres;password=postgres;Timeout=600;CommandTimeout=600;ConnectionLifeTime=600;"); 
using (new ConnectionOpen(conn)) 
using (var ta = conn.BeginTransaction(IsolationLevel.Snapshot)) 
{ 
    IDbCommand command = conn.CreateCommand("SELECT * from stock;"); 
    command.SetTransaction(ta); 
    IDataReader reader = command.ExecuteReader(); 

    int n = 0; 
    while (!reader.IsClosed && reader.Read()) 
    { 
     n++; 

     if (n > 5000) 
     { 
      if (reader != null) 
      { 
       ((NpgsqlDataReader)reader).Close(); 
      } 
     } 
    } 
    ((NpgsqlDataReader)reader).Dispose(); 
    reader = null; 
} 

मैं के लिए देखा है डेटा रीडर वास्तव में बंद नहीं कर सकता है। ऐसा लगता है कि डेटा रीडर पहले सभी पंक्तियों को पढ़ता है और बाद में सामान्य रूप से लौटाता है।

यह उदाहरण एक बड़ा अनुप्रयोग का सार है जहां उपयोगकर्ता एक बटन दबाकर डेटा रीडर को रोक देगा क्योंकि पढ़ने में बहुत लंबा समय लगता है।

उत्तर

0

आप थोड़ी देर लूप में ब्रेक डाल सकते हैं, लेकिन यह सुनिश्चित नहीं है कि आप इसे उपयोगकर्ता कार्रवाई के साथ कैसे जोड़ देंगे ताकि उन्हें पठन लूप से बाहर निकलने का फैसला किया जा सके। वैकल्पिक रूप से आप कोड को पुन: व्यवस्थित कर सकते हैं ताकि यह पंक्तियों की पहली एक्स संख्या लौटा सके और फिर बाकी को वापस करने के लिए या पंक्तियों की अगली एक्स संख्या वापस करने के लिए उन्हें एक जारी रखें बटन दें।

0

यह अनुमान है।

संभव समाधान 1

... 
using (var ta = conn.BeginTransaction(IsolationLevel.Snapshot)) 
{ 
    IDbCommand command = conn.CreateCommand("SELECT * from stock;"); 
    command.SetTransaction(ta); 
    IDataReader reader = command.ExecuteReader(); 

    int n = 5000; 

    //put it in using 
    using(IDataReader reader = command.ExecuteReader()) 
    { 
     //read first N rows 
     for(int i=0;i<n;i++) 
     {   
      //get value from the columns of the current row 
      for (i = 0; i < reader.FieldCount; i++) 
      { 
       Console.Write("{0} \t", reader[i]); 
      } 
     } 
    }  
} 

संभव sollution 2

उपयोग TOP एसक्यूएल आदेश, see samples

+0

मैं अपने परिदृश्य में बाहर छोड़ लॉग आउटपुट की है।मेरे परिदृश्य में डेटा रीडर के व्यवहार की जांच के लिए लॉग आउटपुट हमेशा आदेश के बाद प्रतीक्षा समय दिखाते हैं "((NpgsqlDataReader) पाठक) कुछ सेकंड के।()"। यह प्रतीक्षा समय वही है यदि मैं सभी पंक्तियों को पढ़ता। – Joerg

+0

! सत्य और गलत झूठे मूल्यांकन। सच एक्सओआर झूठी सच का मूल्यांकन करेगा। –

+0

यह सही है, इसे अपडेट करेगा। – oleksii

0

डेटा पाठक आम तौर पर कम से कम डेटाबेस सर्वर से डेटा का हिस्सा देता है (यह SQL सर्वर के साथ काम करता है)। पोस्टग्रे एसक्यूएल कवर के तहत अलग-अलग व्यवहार कर सकता है।

इस पर हमला करने का एक और तरीका पृष्ठभूमि कार्य के रूप में डेटा लोड करना है (BackgroundWorker, Task, आदि)। इस तरह आपका यूआई थ्रेड उत्तरदायी रहता है और इससे कोई फर्क नहीं पड़ता कि पाठक को कवर के तहत कैसे कार्यान्वित किया जाता है।

+0

मुझे नहीं लगता कि एक पृष्ठभूमि वर्कर कंसोल एप्लिकेशन में काम करने जा रहा है। – LarsTech

+0

मैंने इसे किया है। लेकिन कभी-कभी उपयोगकर्ता पहली डेटा पंक्तियों को पढ़ने और प्रदर्शित करने के दौरान विभिन्न डेटा के साथ एक नई क्वेरी शुरू करना चाहता है। और अब मुझे डेटा रीडर को रोकना है और एक नया कमांड रेस शुरू करना है। डेटा रीडर। – Joerg

6

मैं जानता हूँ कि इस सूत्र के बजाय पुरानी है, लेकिन मेरा मानना ​​है कि इस व्यक्ति के सवाल का सही जवाब इस प्रकार है:

command.Cancel(); //execute before closing the reader 
reader.Close(); 

DbCommand.Cancel बुला() रखकर आप का संकेत कर रहे हैं कि आगे कोई रिकॉर्ड करना चाहिए संसाधित हो और आदेश (अंतर्निहित क्वेरी सहित) तुरंत रोकना चाहिए और जल्दी से बाहर निकलना चाहिए। यदि आप कमांड को रद्द नहीं करते हैं, तो जब आप DbDataReader को बंद करने का प्रयास करते हैं (या एक लूप/ब्लॉक का उपयोग करके तोड़ते हैं), और आप बड़ी संख्या में रिकॉर्ड्स लौट रहे हैं, तो बंद() विधि भर जाती है आउटपुट पैरामीटर, रिटर्न वैल्यू, और रिकॉर्ड्स के लिए मूल्य प्रभावित।

यदि आप सभी रिकॉर्ड्स पढ़ने से पहले पाठक को बंद करने का प्रयास करते हैं, तो बंद करें सभी डेटा पढ़ने और उन मानों को भरने का प्रयास करता है, और यह केवल लटकने लगते हैं (संभवत: कुछ प्रकार के टाइमआउट अपवाद के परिणामस्वरूप फेंक दिया)। यदि आपको परिणाम सेट में शेष मानों की परवाह नहीं है - और यदि आप रीड लूप से बाहर हो रहे हैं तो आपको सबसे अधिक संभावना नहीं है - आपको बंद() को कॉल करने से पहले अंतर्निहित कमांड को रद्द करना चाहिए।

उपरोक्त जानकारी के कुछ हिस्सों से लिया गया था: https://www.informit.com/guides/content.aspx?g=dotnet&seqNum=610

+0

यह उत्तर है –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^