Executing Command Asynchronously: पिछले Section में Discuss किए गए Program में एक और समझने वाली बात ये है कि जब तक ArrayList Object पूरी तरह से DataReader Object में Stored Data से Fill नहीं हो जाता, यानी जब तक foreach Loop पूरी तरह से Execute नहीं हो जाता, तब तक निम्न Code Run नहीं होता:
dgAllRecords.DataSource = dbRecordsHolder;
और जब तक ये Code Run नहीं होता, तब तक DataGridView Control में कोई Record Display नहीं होता। चूंकि हमारे इस उदाहरण में Records की संख्या कुल 23 है, इसलिए हमारे DataGridView Control में Display होने वाला Data 1 – 2 Seconds की अविध में Populate हो जाता है।
लेकिन यदि Underlying Data Source से Return होने वाले Records की संख्या हजारों में हो, तो इस DataGridView Object में Records Populate होने में बहुत ही ज्यादा समय लगेगा।
परिणामस्वरूप जब तक सारा Data ArrayList Object में Fill नहीं हो जाएगा, तब तक हमारा Form एक प्रकार से Hanged स्थिति में Freeze हो जाएगा और हमारा Program Use करने वाले User को लगेगा कि हमारा Program काम ही नहीं कर रहा है।
इस प्रकार की स्थिति पैदा न हो, इसके लिए SqlCommand को सामान्यत: Asynchronously Execute किया जाता है और किसी Time Consuming Task को Asynchronously Perform करने के लिए .NET 2.0 में Begin(), End() व IAsyncResult जैसे कुछ न, Methods व Types को Introduce किया गया है।
जब हमारे Command Object के Execute होने पर Underlying Database से बहुत ज्यादा Records Return होते हैं और हम इन Records के ArrayList Object में Populate होते समय अपने Application को Block होने से रोकना चाहते हैं, तब इस प्रकार के Blocking Codes को Execute करने के लिए हमें SqlCommand Object के BeginExecuteReader() Method को Use करना होता है और इसमें एक Callback Method तथा Command Object को Parameter की तरह Pass करना होता है। इस Asynchronous Calling Procedure को हम निम्नानुसार Code द्वारा ज्यादा बेहतर तरीके से समझ सकते हैं:
AsyncCallback callback = new AsyncCallback(DataReaderIsReady);
IAsyncResult asyncResult = testCommand.BeginExecuteReader(callback, testCommand)
यदि हम इस Code को अपने पिछले Example Program के सन्दर्भ में समझें, तो इस Code को हमें ExecuteReader() Method के स्थान पर Replacement के रूप में Use करना होता है। इस तरीके का सबसे मुख्य फायदा ये होता है कि BeginExecuteReader() Method एक Non-Blocking Method है।
यानी जिस समय DataReader Object से ArrayList Object में Data Populating का Task Perform हो रहा होता है, उस समय Program Control फिर से Main() Thread को Return हो जाता है। जिसकी वजह से यदि GUI Application पर User किसी अन्य जरूरत को पूरा करने के लिए Application के अन्य किसी हिस्से को Access करना चाहे, तो वह ऐसा कर सकता है, जबकि Data Populating का Task Background में Internally Perform हो रहा होता है।
इस AsyncCallback Constructor में हमने DataReaderIsReady() मान को Parameter के रूप में Pass किया है, जो कि वह Callback Method है जो उस समय Call होता है, जब BeginExecuteReader() Method पूरी तरह से Execute हो चुका होता है। जबकि इस Method को हम निम्नानुसार तरीके से Define कर सकते हैं:
private void DataReaderIsReady(IAsyncResult result) { MessageBox.Show("Results Loading in ArrayList Object Completed."); SqlCommand testCommand = (SqlCommand)result.AsyncState; SqlDataReader allAuthors = testCommand.EndExecuteReader(result); if(allAuthors.HasRows) { foreach( DbDataRecord record in allAuthors) { dbRecordsHolder.Add(record); } } allAuthors.Close(); }
ये Method तब Execute होता है, जब testCommand.BeginExecuteReader() Method पूरी तरह से Execute हो चुका होता है। जब हम BeginExecuteReader() Method को Call करते हुए Data Reading को Start करते हैं, तब उसी समय हम इस Callback Method को उसमें Parameter की तरह Pass करते हैं, जिसे IAsyncResult.AsyncState Property के माध्यम से Retrieve किया जा सकता है।
जब एक बार हमें SqlCommand Object फिर से प्राप्त हो जाता है, तब हम EndExecuteReader() Method को Execute करके Prepared SqlDataReader Object को प्राप्त कर सकते हैं। इतना होने के बाद हम इस SqlDataReader Object को ठीक उसी तरह से Use कर सकते हैं, जिस तरह से पिछले Program में Use किया था।
अन्तर केवल इतना होता है कि जिस समय SQL Server यानी हमारा Underlying Data Server, हमारे Command Object में Embedded Query को Execute करने तथा Return किए जाने वाले Resultset को तैयार करने में Busy होता है, उस समय हमारा Frontend Application, SQL Server से Data को Retrieve करने के लिए Bind नहीं होता। बल्कि .NET Framework उसे इस बात की Information देता है कि SQL Server ने अपना Result Send करने के लिए तैयार है या नहीं।
चूंकि हमारा उपरोक्त Code किसी एक Single Method तक सीमित नहीं होता, इसलिए हम हमारे Code को using Block का प्रयोग करते हुए Specify नहीं कर सकते। जिसका परिणाम ये होता है कि हमें सभी प्रकार के Cleanup Task स्वयं Perform करने पडते हैं। यानी हमें हमारे Command Object को स्वयं ही Close करना होता है।
इतना करने के साथ ही जब हम Asynchronous तरीके से Execute होने वाला Command Object Create करते हैं, तब हमें Specify किए जाने वाले Connection String में भी निम्नानुसार Asynchronous Processing Parameter को true Set करना जरूरी होता है:
SqlConnectionStringBuilder sqlConBuilder = new SqlConnectionStringBuilder( "Data Source=.\\SQLSERVEREXPRESS; Initial Catalog=pubs; Integrated Security = true; Asynchronous Processing=true");
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook ADO.NET with C# in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
ADO.NET with C# in Hindi | Page:501 | Format: PDF