एंटिटी फ्रेमवर्क: इस कमांड से पहले से ही एक खुला डाटारीडर है


285

मैं एंटिटी फ्रेमवर्क का उपयोग कर रहा हूं और कभी-कभी मुझे यह त्रुटि मिलेगी।

EntityCommandExecutionException
{"There is already an open DataReader associated with this Command which must be closed first."}
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands...

हालांकि मैं कोई मैनुअल कनेक्शन प्रबंधन नहीं कर रहा हूं।

यह त्रुटि रुक-रुक कर होती है।

कोड जो त्रुटि को ट्रिगर करता है (पढ़ने में आसानी के लिए छोटा):

        if (critera.FromDate > x) {
            t= _tEntitites.T.Where(predicate).ToList();
        }
        else {
            t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
        }

हर बार नया कनेक्शन खोलने के लिए डिस्पोज़ पैटर्न का उपयोग करना।

using (_tEntitites = new TEntities(GetEntityConnection())) {

    if (critera.FromDate > x) {
        t= _tEntitites.T.Where(predicate).ToList();
    }
    else {
        t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
    }

}

अभी भी समस्याग्रस्त है

यदि यह पहले से ही खुला है तो EF कनेक्शन का पुन: उपयोग क्यों नहीं करेगा।


1
मुझे पता है कि यह सवाल प्राचीन है, लेकिन मुझे यह जानने में दिलचस्पी होगी कि आपके predicateऔर historicPredicateचर किस प्रकार के हैं। मुझे पता चला है कि यदि आप इसे पास Func<T, bool>करते हैं Where()तो कभी-कभी संकलन करेंगे और काम करेंगे (क्योंकि यह स्मृति में "जहां" करता है)। आपको जो करना चाहिए वह कर रहा Expression<Func<T, bool>>है Where()
जेम्स

जवाबों:


351

यह समापन कनेक्शन के बारे में नहीं है। EF कनेक्शन को सही ढंग से प्रबंधित करता है। इस समस्या के बारे में मेरी समझ यह है कि एकल कनेक्शन (या एकाधिक चयनों के साथ एकल आदेश) पर निष्पादित कई डेटा पुनर्प्राप्ति आदेश हैं जबकि पहले डेटा रीडिंग पूरा होने से पहले डेटारीडर निष्पादित किया जाता है। अपवाद से बचने का एकमात्र तरीका कई नेस्टेड DataReaders को अनुमति देना = MultipleActiveResultSets चालू करना है। एक और परिदृश्य जब यह हमेशा होता है जब आप क्वेरी (IQueryable) के परिणाम के माध्यम से पुनरावृति करते हैं और आप पुनरावृत्ति के लिए भरी हुई इकाई के लिए आलसी लोडिंग को ट्रिगर करेंगे।


2
यह समझ में आता है। लेकिन प्रत्येक विधि के भीतर केवल एक ही चयन है।
सोनिक सोल

1
@ ध्वनि: यह सवाल है। हो सकता है कि तब एक और कमांड निष्पादित हो लेकिन आप इसे नहीं देखते हैं। मुझे यकीन नहीं है कि अगर यह प्रोइलर में पता लगाया जा सकता है (अपवाद को दूसरे पाठक के निष्पादित होने से पहले फेंक दिया जा सकता है)। आप क्वेरी को ObjectQuery में डालने का प्रयास कर सकते हैं और SQL कमांड देखने के लिए ToTraceString को कॉल कर सकते हैं। इसे ट्रैक करना मुश्किल है। मैं हमेशा MARS चालू करता हूं।
लादिस्लाव मृंका

2
@ ध्वनि: नहीं मेरा इरादा निष्पादित और पूर्ण SQL आदेशों की जाँच करना था।
लादिस्लाव मृका

11
महान, मेरी समस्या दूसरा परिदृश्य था: 'जब आप क्वेरी (IQueryable) के परिणाम के माध्यम से पुनरावृति करेंगे और आप पुनरावृत्ति के लिए भरी हुई इकाई के लिए आलसी लोडिंग को ट्रिगर करेंगे।'
अमृत ​​एल्गारि

6
MARS को सक्षम करने से जाहिर तौर पर इसके बुरे प्रभाव हो सकते हैं: designlimbo.com/?p=235
Søren Boisen

126

वैकल्पिक रूप से MARS (MultipleActiveResultSets) का उपयोग करके आप अपना कोड लिख सकते हैं ताकि आप कई परिणाम सेट न खोलें।

आप डेटा को मेमोरी में पुनः प्राप्त करने के लिए क्या कर सकते हैं, इस तरह से आपके पास रीडर नहीं होगा। यह अक्सर एक परिणाम के माध्यम से पुनरावृत्ति करने के कारण होता है, जबकि एक और परिणाम सेट खोलने की कोशिश करता है।

नमूना कोड:

public class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

public class Blog
{
    public int BlogID { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int PostID { get; set; }
    public virtual Blog Blog { get; set; }
    public string Text { get; set; }
}

कहते हैं कि आप अपने डेटाबेस में एक खोज कर रहे हैं जिसमें ये शामिल हैं:

var context = new MyContext();

//here we have one resultset
var largeBlogs = context.Blogs.Where(b => b.Posts.Count > 5); 

foreach (var blog in largeBlogs) //we use the result set here
{
     //here we try to get another result set while we are still reading the above set.
    var postsWithImportantText = blog.Posts.Where(p=>p.Text.Contains("Important Text"));
}

हम जोड़कर इस के लिए एक सरल उपाय कर सकते हैं .ToList () इस तरह:

var largeBlogs = context.Blogs.Where(b => b.Posts.Count > 5).ToList();

यह स्मृति में सूची को लोड करने के लिए एंटिफ्रेमवर्क को बाध्य करता है, इस प्रकार जब हम इसे पुन: व्यवस्थित करते हैं, जबकि यह फ़ॉरच लूप में होता है तो यह सूची को खोलने के लिए डेटा रीडर का उपयोग नहीं करता है, यह इसके बजाय मेमोरी में होता है।

मुझे एहसास है कि अगर आप उदाहरण के लिए कुछ गुणों को आलसी करना चाहते हैं तो यह वांछित नहीं हो सकता है। यह ज्यादातर एक उदाहरण है जो उम्मीद करता है कि यह बताता है कि आपको यह समस्या कैसे / क्यों हो सकती है, इसलिए आप तदनुसार निर्णय ले सकते हैं


7
इस समाधान ने मेरे लिए काम किया। जोड़ें .ToList () क्वेरी के ठीक बाद और परिणाम के साथ कुछ और करने से पहले।
TJKjaer

9
इससे सावधान रहें और सामान्य ज्ञान का उपयोग करें। यदि आप ToListएक हज़ार वस्तुओं का अंतर्ग्रहण कर रहे हैं, तो यह एक टन मेमोरी को बढ़ाने वाला है। इस विशिष्ट उदाहरण में, आप पहले के साथ आंतरिक क्वेरी के संयोजन से बेहतर होंगे ताकि दो के बजाय केवल एक क्वेरी उत्पन्न हो।
कामरानिकस

4
@subkamran मेरी बात बिल्कुल यही थी, किसी चीज के बारे में सोचना और चुनना कि स्थिति के लिए क्या सही है, न कि सिर्फ करना। उदाहरण सिर्फ कुछ यादृच्छिक है जिसे मैंने समझाया था :)
जिम वोल्फ

3
निश्चित रूप से, मैं बस इसे कॉपी / पेस्ट करने वाले लोगों के लिए स्पष्ट रूप से इंगित करना चाहता था :)
kamranicus

मुझे गोली मत चलाना, लेकिन यह सवाल का कोई समाधान नहीं है। एसक्यूएल से संबंधित समस्या का हल कब से "मेमोरी में डेटा खींच रहा है" है? मुझे डेटाबेस के साथ चैट करना पसंद है, इसलिए किसी भी तरह से मैं मेमोरी में कुछ खींचना पसंद नहीं करूंगा "क्योंकि अन्यथा एक एसक्यूएल अपवाद फेंक दिया जाता है"। फिर भी, आपको प्रदान किए गए कोड में, दो बार डेटाबेस से संपर्क करने का कोई कारण नहीं है। एक कॉल में करना आसान है। इस तरह की पोस्ट से सावधान रहें। ToList, First, Single, ... का उपयोग केवल तब किया जाना चाहिए जब डेटा की आवश्यकता मेमोरी में होती है (इसलिए केवल वह डेटा जो आप चाहते हैं), तब नहीं जब SQL अपवाद अन्यथा उत्पन्न हो रहा हो।
फ्रेडरिक प्रेज

70

इस समस्या को दूर करने का एक और तरीका है। यह एक बेहतर तरीका है या नहीं यह आपकी स्थिति पर निर्भर करता है।

आलसी लोडिंग से समस्या उत्पन्न होती है, इसलिए इससे बचने का एक तरीका यह है कि शामिल करने के माध्यम से आलसी लोडिंग न करें:

var results = myContext.Customers
    .Include(x => x.Orders)
    .Include(x => x.Addresses)
    .Include(x => x.PaymentMethods);

यदि आप उपयुक्त Includes का उपयोग करते हैं , तो आप MARS को सक्षम करने से बच सकते हैं। लेकिन अगर आप एक चूक करते हैं, तो आपको त्रुटि मिलेगी, इसलिए मार्स को सक्षम करना शायद इसे ठीक करने का सबसे आसान तरीका है।


1
एक जादू की तरह काम किया। .IncludeMARS को सक्षम करने की तुलना में बेहतर समाधान है, और अपने स्वयं के SQL क्वेरी कोड लिखने की तुलना में बहुत आसान है।
नोलोनार

15
यदि किसी को यह समस्या हो रही है कि आप केवल .Include ("string") को लैम्बडा नहीं लिख सकते हैं, तो आपको "System.Data.Entity" का उपयोग करके जोड़ना होगा क्योंकि एक्सटेंशन विधि वहां स्थित है।
जिम वोल्फ

46

आपको यह त्रुटि तब होती है, जब आप जिस संग्रह को पुनरावृत्त करने की कोशिश कर रहे हैं वह एक प्रकार का आलसी लोडिंग (IQueriable) है।

foreach (var user in _dbContext.Users)
{    
}

अन्य संग्रहणीय संग्रह में IQueriable संग्रह परिवर्तित करने से यह समस्या हल हो जाएगी। उदाहरण

_dbContext.Users.ToList()

नोट: .TLList () हर बार एक नया सेट बनाता है और यदि आप बड़े डेटा के साथ काम कर रहे हैं तो यह प्रदर्शन समस्या का कारण बन सकता है।


1
सबसे आसान संभव उपाय! बिग यूपी;)
जैकब सोबस

1
अनबाउंड सूचियाँ प्राप्त करने से गंभीर प्रदर्शन समस्याएँ हो सकती हैं! कोई कैसे उखाड़ सकता है?
22

1
@ सैंडरॉक किसी ऐसे व्यक्ति के लिए नहीं जो किसी छोटी कंपनी के लिए काम करता हो - SELECT COUNT(*) FROM Users= 5
साइमन_वेअर

5
इसके बारे में दो बार सोचें। यह क्यू / ए पढ़ने वाला एक युवा डेवलपर सोच सकता है कि यह एक सर्वकालिक समाधान है जब यह बिल्कुल नहीं है। मेरा सुझाव है कि आप अपने उत्तर को संपादित करने के लिए db से अनबाउंड लिस्ट लाने के खतरे के बारे में पाठकों को चेतावनी देते हैं।
सैंडरॉक

1
@SandRock मुझे लगता है कि यह आपके लिए एक अच्छा स्थान होगा कि आप सर्वोत्तम प्रथाओं का वर्णन करने वाले उत्तर या लेख को लिंक करें।
सिंजई

13

मैंने निर्माणकर्ता के विकल्प को जोड़कर आसानी से (व्यावहारिक) समस्या को हल किया। इस प्रकार, मैं जरूरत पड़ने पर ही इसका उपयोग करता हूं।

public class Something : DbContext
{
    public Something(bool MultipleActiveResultSets = false)
    {
        this.Database
            .Connection
            .ConnectionString = Shared.ConnectionString /* your connection string */
                              + (MultipleActiveResultSets ? ";MultipleActiveResultSets=true;" : "");
    }
...

2
धन्यवाद। यह काम कर रहा है। मैंने सीधे कई स्ट्रिंग जोड़े। कनेक्शन में सीधे सीधे web.config में
मोशनअफ्रीसेटसेट

11

सेट करने के लिए अपने कनेक्शन स्ट्रिंग में प्रयास करें MultipleActiveResultSets=true। यह डेटाबेस पर मल्टीटास्किंग की अनुमति देता है।

Server=yourserver ;AttachDbFilename=database;User Id=sa;Password=blah ;MultipleActiveResultSets=true;App=EntityFramework

यह मेरे लिए काम करता है ... चाहे आपका कनेक्शन app.config में हो या आप इसे प्रोग्रामेटिक रूप से सेट करें ... आशा है कि यह मददगार होगा


MultipleActiveResultSets = सही आपके कनेक्शन स्ट्रिंग में जोड़ा गया समस्या का समाधान होगा। यह डाउन-वोट नहीं होना चाहिए था।
एरोन हुडोन

हां, यकीन है कि मैं अपने कनेक्शन स्ट्रिंग में जोड़ने के लिए प्रदर्शन किया है
मोहम्मद Hocine

4

मैंने मूल रूप से MyDataContext ऑब्जेक्ट (जहाँ MyDataContext एक EF5 प्रसंग ऑब्जेक्ट है) के उदाहरण को संदर्भित करने के लिए अपने API वर्ग में एक स्थिर फ़ील्ड का उपयोग करने का निर्णय लिया था, लेकिन समस्या पैदा करने के लिए ऐसा लगता है। मैंने अपनी एपीआई विधियों में से प्रत्येक में निम्नलिखित की तरह कोड जोड़ा और इसने समस्या को ठीक कर दिया।

using(MyDBContext db = new MyDBContext())
{
    //Do some linq queries
}

जैसा कि अन्य लोगों ने कहा है, EF डेटा संदर्भ ऑब्जेक्ट थ्रेड सुरक्षित नहीं हैं। तो उन्हें स्थिर वस्तु में रखने से अंततः सही परिस्थितियों में "डेटा रीडर" त्रुटि का कारण होगा।

मेरी मूल धारणा यह थी कि ऑब्जेक्ट का केवल एक उदाहरण बनाना अधिक कुशल होगा, और बेहतर मेमोरी प्रबंधन का खर्च उठाएगा। मैंने इस मुद्दे पर जो शोध किया है, उससे ऐसा नहीं है। वास्तव में, यह एक अलग, धागा सुरक्षित घटना के रूप में अपने एपीआई के लिए प्रत्येक कॉल का इलाज करने के लिए अधिक कुशल प्रतीत होता है। यह सुनिश्चित करना कि सभी संसाधन ठीक से जारी किए गए हैं, क्योंकि ऑब्जेक्ट गुंजाइश से बाहर हो जाता है।

यह विशेष रूप से समझ में आता है यदि आप अपने एपीआई को अगली प्राकृतिक प्रगति पर ले जाते हैं जो इसे वेबसर्विस या रीस्ट एपीआई के रूप में उजागर करना होगा।

प्रकटीकरण

  • ओएस: विंडोज सर्वर 2012
  • .NET: स्थापित 4.5, परियोजना 4.0 का उपयोग कर
  • डेटा स्रोत: MySQL
  • आवेदन की रूपरेखा: MVC3
  • प्रमाणीकरण: प्रपत्र

3

मैंने देखा कि यह त्रुटि तब होती है जब मैं देखने के लिए एक IQueriable भेज देता हूं और इसका उपयोग डबल फ़ॉरचेक में करता हूं, जहां आंतरिक फ़ॉर्च कनेक्शन का उपयोग करने की भी आवश्यकता होती है। सरल उदाहरण (ViewBag.parents IQueriable या DbSet हो सकता है):

foreach (var parent in ViewBag.parents)
{
    foreach (var child in parent.childs)
    {

    }
}

इसका उपयोग .ToList()करने से पहले सरल समाधान संग्रह पर उपयोग करना है। यह भी ध्यान दें कि MARS MySQL के साथ काम नहीं करता है।


धन्यवाद! यहाँ पर सब कुछ कहा "नेस्टेड लूप्स समस्या है" लेकिन किसी ने यह नहीं कहा कि इसे कैसे ठीक किया जाए। मैंने ToList()DB से एक संग्रह प्राप्त करने के लिए अपने पहले कॉल पर रखा । फिर मैंने foreachउस सूची पर किया और बाद की कॉल ने त्रुटि देने के बजाय पूरी तरह से काम किया।
अल्बाट्रॉस

@AlbatrossCafe ... लेकिन किसी ने यह उल्लेख नहीं किया कि उस स्थिति में आपके डेटा को मेमोरी में लोड किया जाएगा और डीबी के बजाय मेमोरी में क्वेरी को निष्पादित किया जाएगा
लाइटनिंग 3

3

मैंने पाया कि मैं एक ही त्रुटि थी, और यह उस समय हुआ जब मैं एक उपयोग कर रहा था Func<TEntity, bool>एक के बजाय Expression<Func<TEntity, bool>>अपने लिए predicate

एक बार जब मैंने सभी अपवादों Func'sको बदल Expression'sदिया तो उन्हें फेंक दिया जाना बंद हो गया।

मेरा मानना ​​है कि EntityFramworkकुछ चालाक चीजें Expression'sकरता है जिसके साथ यह बस नहीं करता हैFunc's


इसके लिए अधिक उर्जा की जरूरत है। मैं अपने DataContext वर्ग में एक विधि तैयार करने की कोशिश कर रहा था (MyTParent model, Func<MyTChildren, bool> func)ताकि मेरे ViewModels whereजेनेरिक DataContext विधि के लिए एक निश्चित खंड निर्दिष्ट कर सके । जब तक मैंने ऐसा नहीं किया तब तक कुछ भी काम नहीं कर रहा था।
जस्टिन

3

इस समस्या को कम करने के लिए 2 समाधान:

  1. फोर्स मैमोरी कैशिंग आलसी लोडिंग को ध्यान में रखते हुए .ToList()अपनी क्वेरी के बाद , ताकि आप इसके माध्यम से एक नया DataReader खोल सकते हैं।
  2. .Include(/ आपके द्वारा क्वेरी में लोड की जाने वाली अतिरिक्त इकाइयाँ ) इसे उत्सुक लोडिंग कहा जाता है, जो आपको DataReader के साथ क्वेरी के निष्पादन के दौरान संबद्ध ऑब्जेक्ट्स (निकाय) को शामिल करने की अनुमति देता है।

2

MARS को सक्षम करने और मेमोरी में सेट किए गए पूरे परिणाम को पुनः प्राप्त करने के बीच एक अच्छा मध्य-मैदान केवल एक प्रारंभिक क्वेरी में IDs को पुनः प्राप्त करना है, और फिर आईडी के माध्यम से लूप के रूप में प्रत्येक इकाई को भौतिक रूप से चलते हैं।

उदाहरण के लिए ( इस उत्तर में "ब्लॉग और पोस्ट" नमूना संस्थाओं का उपयोग करके ):

using (var context = new BlogContext())
{
    // Get the IDs of all the items to loop through. This is
    // materialized so that the data reader is closed by the
    // time we're looping through the list.
    var blogIds = context.Blogs.Select(blog => blog.Id).ToList();

    // This query represents all our items in their full glory,
    // but, items are only materialized one at a time as we
    // loop through them.
    var blogs =
        blogIds.Select(id => context.Blogs.First(blog => blog.Id == id));

    foreach (var blog in blogs)
    {
        this.DoSomethingWith(blog.Posts);

        context.SaveChanges();
    }
}

ऐसा करने का अर्थ है कि आप केवल कुछ हज़ार पूर्णांकों को मेमोरी में खींचते हैं, हजारों ऑब्जेक्ट ऑब्जेक्ट के विपरीत, जो आपको MARS को सक्षम किए बिना आइटम-बाय-आइटम को सक्षम करने के लिए मेमोरी उपयोग को कम से कम करना चाहिए।

इसका एक और अच्छा लाभ, जैसा कि नमूने में देखा गया है, कि आप लूप के अंत तक प्रतीक्षा करने के बजाय प्रत्येक आइटम के माध्यम से लूप में बदलाव कर सकते हैं (या कुछ अन्य वर्कअराउंड), जैसा कि इसके साथ भी आवश्यक होगा मार्स सक्षम (देखें) यहां और यहां )।


context.SaveChanges();इनसाइड लूप :(। यह अच्छा नहीं है। यह लूप के बाहर होना चाहिए।
जवान सिंह

1

मेरे मामले में मैंने पाया कि myContext.SaveChangesAsync () कॉल से पहले "वेट" कथन गायब थे। उन async कॉल से पहले वेट जोड़ना मेरे लिए डेटा रीडर समस्याएँ तय करता है।


0

यदि हम अपनी शर्तों का हिस्सा किसी फंक <> या विस्तार विधि में समूहित करने का प्रयास करते हैं, तो हमें यह त्रुटि मिलेगी, मान लें कि हमारे पास एक कोड है:

public static Func<PriceList, bool> IsCurrent()
{
  return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
              (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

Or

public static IEnumerable<PriceList> IsCurrent(this IEnumerable<PriceList> prices) { .... }

यदि हम इसका उपयोग करने की कोशिश करते हैं तो अपवाद को फेंक दिया जाएगा (जैसे), इसके बजाय हमें क्या करना चाहिए:

public static Expression<Func<PriceList, bool>> IsCurrent()
{
    return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
                (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

इसके अलावा और अधिक पढ़ा जा सकता है: http://www.albahari.com/nutshell/predicatebuilder.aspx


0

इस समस्या को केवल डेटा को किसी सूची में परिवर्तित करके हल किया जा सकता है

 var details = _webcontext.products.ToList();


            if (details != null)
            {
                Parallel.ForEach(details, x =>
                {
                    Products obj = new Products();
                    obj.slno = x.slno;
                    obj.ProductName = x.ProductName;
                    obj.Price = Convert.ToInt32(x.Price);
                    li.Add(obj);

                });
                return li;
            }

ToList () कॉल करता है लेकिन उपरोक्त कोड अभी भी कनेक्शन का निपटान नहीं करता है। इसलिए आपके _webcontext को लाइन 1 के समय बंद होने का खतरा है
सोनिक सोल

0

मेरी स्थिति में समस्या निर्भरता इंजेक्शन पंजीकरण के कारण हुई। मैं प्रति अनुरोध स्कोप सेवा को इंजेक्ट कर रहा था जो एक एकल पंजीकृत सेवा में dbcontext का उपयोग कर रहा था। वहाँ dbcontext कई अनुरोध के भीतर इस्तेमाल किया गया था और इसलिए त्रुटि।


0

मेरे मामले में इस मुद्दे का MARS कनेक्शन स्ट्रिंग के साथ कुछ भी नहीं था, लेकिन json क्रमांकन के साथ। मेरे प्रोजेक्ट को NetCore2 से 3 में अपग्रेड करने के बाद मुझे यह त्रुटि मिली।

अधिक जानकारी यहां पाई जा सकती है


-6

मैंने दूसरी क्वेरी से पहले कोड के निम्नलिखित अनुभाग का उपयोग करके इस समस्या को हल किया:

 ...first query
 while (_dbContext.Connection.State != System.Data.ConnectionState.Closed)
 {
     System.Threading.Thread.Sleep(500);
 }
 ...second query

आप मिल्क सेकंड में सोने का समय बदल सकते हैं

पीडी थ्रेड्स का उपयोग करते समय उपयोगी


13
मनमाने ढंग से थ्रेड को जोड़ना।किसी भी घोल में सो जाना बुरा अभ्यास है - और विशेष रूप से बुरा है जब एक अलग समस्या को दूर करने के लिए उपयोग किया जाता है जहां कुछ मूल्य की स्थिति को पूरी तरह से समझा नहीं जाता है। मैंने सोचा होगा कि प्रतिक्रिया के नीचे बताए अनुसार "थ्रेड्स का उपयोग करना" का अर्थ होगा थ्रेडिंग की कम से कम कुछ बुनियादी समझ होना - लेकिन यह प्रतिक्रिया किसी भी संदर्भ को ध्यान में नहीं रखती है, खासकर उन परिस्थितियों में जहां यह बहुत बुरा विचार है। थ्रेड स्लीप का उपयोग करने के लिए - जैसे कि UI थ्रेड पर।
माइक टूर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.