50 मिसे के लिए सोने के लिए मुझे मेरा C # प्रोग्राम कैसे मिलेगा?


272

50 मिलीसेकेंड सोने के लिए मुझे मेरा C # प्रोग्राम कैसे मिलेगा?

यह एक आसान सवाल लग सकता है, लेकिन मैं एक अस्थायी मस्तिष्क विफलता पल रहा हूँ!


1
VB.NET को फिर से टैग किया जाता है क्योंकि उत्तर वहां भी काम करता है।
DrFloyd5

कोई DrFloyd5, VB.NET पर काम नहीं करता है, है ना?
ज़ानोनी

16
अगर मैं VB.Net टीम पर होता, तो मैं जोड़ता; भाषा के अगले संस्करण के लिए एक टिप्पणी चरित्र के रूप में ...
जोएल कोएहॉर्न

4
मुझे लगता है कि VB प्रोग्रामर को बराबर समझने के लिए काफी उज्ज्वल हैं ..
BlueRaja - Danny Pflughoeft

ठीक है, बस सुनिश्चित करने के लिए, अब वे नहीं है।
साइकोडाटा

जवाबों:


330
System.Threading.Thread.Sleep(50);

हालाँकि याद रखें, कि मुख्य GUI थ्रेड में ऐसा करने से आपका GUI अपडेट होने से अवरुद्ध हो जाएगा (यह "सुस्त" महसूस होगा)

बस ;VB.net के लिए भी काम करने के लिए इसे हटा दें ।


एक विधि में नींद को बुलाने के बाद, क्या कार्यक्रम पृष्ठभूमि में (नए थ्रेड को बनाए बिना) निष्पादित करना जारी रखेगा? इसके अलावा, अगर मैं एक नए धागे में नींद कहता हूं, तो क्या मुख्य धागा अपना काम जारी रखेगा?
जय निर्गुडकर

@JayNirgudkar स्लीप को कॉल करने वाले थ्रेड को रोक दिया जाएगा। अन्य धागे प्रभावित नहीं होते हैं।
इसक सावो

यह सटीक होने की गारंटी नहीं है।
अकुमबर्न 18

150

किसी भी प्रोग्रामिंग भाषा में प्रतीक्षा करने के लिए मूल रूप से 3 विकल्प हैं:

  1. ढीली प्रतीक्षा
    • दिए गए समय के लिए थ्रेड ब्लॉक निष्पादित करना (= प्रसंस्करण शक्ति का उपभोग नहीं करता है)
    • अवरुद्ध / प्रतीक्षा धागे पर कोई प्रसंस्करण संभव नहीं है
    • इतना सटीक नहीं है
  2. टाइट वेटिंग (जिसे टाइट लूप भी कहा जाता है)
    • प्रोसेसर पूरे प्रतीक्षा अंतराल के लिए बहुत व्यस्त है (वास्तव में, यह आमतौर पर एक कोर के प्रसंस्करण समय का 100% खपत करता है)
    • प्रतीक्षा करते समय कुछ क्रियाएं की जा सकती हैं
    • बहुत स्पष्ट
  3. पिछले 2 का संयोजन
    • यह आम तौर पर 1. की प्रसंस्करण क्षमता को जोड़ती है और 2 के कुछ करने के लिए प्राथमिकता + क्षमता।

1. के लिए - C # में ढीली प्रतीक्षा करें:

Thread.Sleep(numberOfMilliseconds);

हालाँकि, विंडोज़ थ्रेड शेड्यूलर की अशुद्धि का कारण Sleep()लगभग 15ms है (इसलिए नींद आसानी से 20ms तक प्रतीक्षा कर सकती है, भले ही वह केवल 1ms के लिए प्रतीक्षा करने के लिए निर्धारित हो)।

2 के लिए - C # में टाइट वेटिंग है:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do possible
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
}

हम DateTime.Nowसमय मापन के अन्य साधनों का भी उपयोग कर सकते हैं , लेकिन Stopwatchयह बहुत तेज़ है (और यह वास्तव में तंग लूप में दिखाई देगा)।

3. के लिए - संयोजन:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do STILL POSSIBLE
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
    Thread.Sleep(1); //so processor can rest for a while
}

यह कोड नियमित रूप से 1ms (या थोड़ा और अधिक, ओएस थ्रेड शेड्यूलिंग पर निर्भर करता है) के लिए धागे को अवरुद्ध करता है, इसलिए प्रोसेसर अवरुद्ध होने के उस समय के लिए व्यस्त नहीं है और कोड प्रोसेसर की 100% शक्ति का उपभोग नहीं करता है। अन्य प्रसंस्करण अभी भी बीच में अवरुद्ध किया जा सकता है (जैसे: यूआई का अद्यतन करना, घटनाओं से निपटना या बातचीत / संचार सामग्री करना)।


1
टाइमर भी रुचि का हो सकता है
जॉनी राया

55

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


44

चूंकि अब आपके पास async / प्रतीक्षा सुविधा है, 50ms के लिए सोने का सबसे अच्छा तरीका टास्क है।

async void foo()
{
    // something
    await Task.Delay(50);
}

या यदि आप .NET 4 को लक्षित कर रहे हैं (VS2010 या Microsoft.Bcl.Async के लिए Async CTP 3 के साथ), तो आपको यह करना होगा:

async void foo()
{
    // something
    await TaskEx.Delay(50);
}

इस तरह से आप UI थ्रेड को ब्लॉक नहीं करेंगे।


आप इस देरी के दौरान प्रतिक्रिया कर सकते हैं, अगर यह एक लूप में है?
तेमन शिपही

नहीं तुम नहीं कर सकते। मेरा मानना ​​है कि एक FlushAsyncसंस्करण है।
टोनी पेट्रीना

6
एक विकल्प जिसके asyncलिए घोषणा की आवश्यकता नहीं होती हैTask.Delay(50).Wait();
स्टुअर्ट


14
Thread.Sleep(50);

निर्दिष्ट समय की मात्रा के लिए ऑपरेटिंग सिस्टम द्वारा निष्पादन के लिए धागा निर्धारित नहीं किया जाएगा। यह विधि WaitSleepJoin को शामिल करने के लिए थ्रेड की स्थिति को बदलता है।

यह विधि मानक COM और SendMessage पंपिंग नहीं करती है। यदि आपको थ्रेड पर सोने की आवश्यकता है जिसमें STAThreadAttribute है, लेकिन आप मानक COM और SendMessage पम्पिंग करना चाहते हैं, तो टाइमआउट अंतराल निर्दिष्ट करने वाली जॉइन विधि के अधिभार में से एक का उपयोग करने पर विचार करें।

Thread.Join


0

.NET फ्रेमवर्क 4.5 के साथ शुरू, आप उपयोग कर सकते हैं:

using System.Threading.Tasks;

Task.Delay(50).Wait();   // wait 50ms

-1

दोनों ओर से लाभदायक:

using System.Runtime.InteropServices;

    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
    private static extern uint TimeBeginPeriod(uint uMilliseconds);

    [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
    private static extern uint TimeEndPeriod(uint uMilliseconds);
    /**
     * Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
     */
    private void accurateSleep(int milliseconds)
    {
        //Increase timer resolution from 20 miliseconds to 1 milisecond
        TimeBeginPeriod(1);
        Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
        stopwatch.Start();

        while (stopwatch.ElapsedMilliseconds < milliseconds)
        {
            //So we don't burn cpu cycles
            if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
            {
                Thread.Sleep(5);
            }
            else
            {
                Thread.Sleep(1);
            }
        }

        stopwatch.Stop();
        //Set it back to normal.
        TimeEndPeriod(1);
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.