किसी भी समय आपको एक दूरस्थ सर्वर पर कार्रवाई करने की आवश्यकता होती है, आपका कार्यक्रम अनुरोध उत्पन्न करता है, भेजता है, फिर प्रतिक्रिया का इंतजार करता है। मैं का उपयोग करेगा SaveChanges()
और SaveChangesAsync()
एक उदाहरण के रूप लेकिन एक ही लागू होता है Find()
और FindAsync()
।
मान लें कि आपके पास myList
100 + आइटमों की एक सूची है , जिन्हें आपको अपने डेटाबेस में जोड़ना होगा। डालने के लिए, आपका कार्य कुछ इस तरह दिखाई देगा:
using(var context = new MyEDM())
{
context.MyTable.AddRange(myList);
context.SaveChanges();
}
सबसे पहले आप एक उदाहरण बनाते MyEDM
हैं, सूची myList
को तालिका में जोड़ते हैं MyTable
, फिर SaveChanges()
डेटाबेस में परिवर्तन जारी रखने के लिए कॉल करते हैं। यह काम करता है कि आप कैसे चाहते हैं, रिकॉर्ड प्रतिबद्ध हो जाते हैं, लेकिन जब तक कमिट खत्म नहीं हो जाता, तब तक आपका प्रोग्राम कुछ और नहीं कर सकता। आप जो कर रहे हैं उसके आधार पर यह एक लंबा समय ले सकता है। यदि आप रिकॉर्ड्स में बदलाव कर रहे हैं, तो इकाई को एक समय में एक (मुझे एक बार अपडेट के लिए 2 मिनट बचाने के लिए) प्रतिबद्ध करना होगा!
इस समस्या को हल करने के लिए, आप दो चीजों में से एक कर सकते हैं। पहला आप सम्मिलित करने के लिए एक नया धागा शुरू कर सकते हैं। हालांकि यह कॉलिंग थ्रेड को निष्पादित करने के लिए मुक्त करेगा, आपने एक नया थ्रेड बनाया है जो बस वहां बैठने और प्रतीक्षा करने वाला है। उस ओवरहेड की कोई आवश्यकता नहीं है, और यह वही है जो async await
पैटर्न हल करता है।
आई / ओ ओपेरशन के लिए, await
जल्दी से आपका सबसे अच्छा दोस्त बन जाता है। ऊपर से कोड अनुभाग लेते हुए, हम इसे संशोधित कर सकते हैं:
using(var context = new MyEDM())
{
Console.WriteLine("Save Starting");
context.MyTable.AddRange(myList);
await context.SaveChangesAsync();
Console.WriteLine("Save Complete");
}
यह एक बहुत छोटा परिवर्तन है, लेकिन आपके कोड की दक्षता और प्रदर्शन पर गहरा प्रभाव पड़ता है। तो क्या होता है? कोड की भीख एक समान है, आप इसका एक उदाहरण बनाते हैं MyEDM
और अपने myList
को जोड़ते हैं MyTable
। लेकिन जब आप कॉल करते हैं await context.SaveChangesAsync()
, तो कोड का निष्पादन कॉलिंग फ़ंक्शन पर लौट जाता है! इसलिए जब आप उन सभी रिकॉर्डों के लिए इंतजार कर रहे हैं, तो आपका कोड निष्पादित करना जारी रख सकता है। उस फ़ंक्शन को कहें जिसमें उपरोक्त कोड का हस्ताक्षर था public async Task SaveRecords(List<MyTable> saveList)
, कॉलिंग फ़ंक्शन इस तरह दिख सकता है:
public async Task MyCallingFunction()
{
Console.WriteLine("Function Starting");
Task saveTask = SaveRecords(GenerateNewRecords());
for(int i = 0; i < 1000; i++){
Console.WriteLine("Continuing to execute!");
}
await saveTask;
Console.Log("Function Complete");
}
आपके पास इस तरह का एक समारोह क्यों होगा, मुझे नहीं पता, लेकिन यह क्या आउटपुट दिखाता है कि कैसे async await
काम करता है। पहले जाने कि क्या होता है।
निष्पादन प्रवेश करता है MyCallingFunction
, Function Starting
फिर Save Starting
कंसोल को लिखा जाता है, फिर फ़ंक्शन SaveChangesAsync()
को कॉल किया जाता है। इस बिंदु पर, निष्पादन MyCallingFunction
1000 बार तक लूप लेखन 'कंटीन्यूइंग टू एक्स्यूट्यूट' के लिए वापस आता है और प्रवेश करता है। जब SaveChangesAsync()
खत्म हो जाता है, तो SaveRecords
फंक्शन Save Complete
कंसोल पर लिखते हुए फंक्शन पर वापस आ जाता है। एक बार जब सब कुछ SaveRecords
पूरा हो जाता है, तो निष्पादन जारी रहेगा MyCallingFunction
जब यह SaveChangesAsync()
समाप्त हो गया था । उलझन में? यहाँ एक उदाहरण आउटपुट है:
कार्य प्रारंभ करना
शुरू बचाओ
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
....
निरंतर निष्पादित करने के लिए!
पूरा बचाओ!
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
....
निरंतर निष्पादित करने के लिए!
कार्य पूर्ण!
या हो सकता है:
कार्य प्रारंभ करना
शुरू बचाओ
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
पूरा बचाओ!
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
निरंतर निष्पादित करने के लिए!
....
निरंतर निष्पादित करने के लिए!
कार्य पूर्ण!
यह सौंदर्य की बात है async await
, जब आप किसी चीज के खत्म होने का इंतजार कर रहे हैं तो आपका कोड चलना जारी रख सकता है। वास्तव में, आपके पास अपने कॉलिंग फ़ंक्शन के रूप में इस तरह का एक फ़ंक्शन होगा:
public async Task MyCallingFunction()
{
List<Task> myTasks = new List<Task>();
myTasks.Add(SaveRecords(GenerateNewRecords()));
myTasks.Add(SaveRecords2(GenerateNewRecords2()));
myTasks.Add(SaveRecords3(GenerateNewRecords3()));
myTasks.Add(SaveRecords4(GenerateNewRecords4()));
await Task.WhenAll(myTasks.ToArray());
}
यहां, आपके पास एक ही समय में चार अलग-अलग सेव रिकॉर्ड फ़ंक्शन हैं । व्यक्तिगत कार्यों को श्रृंखला में बुलाए जाने की तुलना में MyCallingFunction
बहुत तेज़ी से पूरा होगा ।async await
SaveRecords
एक चीज जिसे मैंने अभी तक नहीं छुआ है वह है await
कीवर्ड। यह क्या करता है वर्तमान फ़ंक्शन को तब तक निष्पादित करने से रोकना है जब तक कि Task
आप जो भी पूरी होने का इंतजार कर रहे हैं। तो मूल के मामले में MyCallingFunction
, लाइन Function Complete
को कंसोल तक नहीं लिखा जाएगाSaveRecords
फ़ंक्शन को खत्म होने ।
लंबी कहानी छोटी, यदि आपके पास उपयोग करने का विकल्प है async await
, तो आपको ऐसा करना चाहिए क्योंकि यह आपके आवेदन के प्रदर्शन को बढ़ा देगा।