আমি কীভাবে আমার সি # প্রোগ্রামটি 50 এমসিতে ঘুমাতে পারি?


272

আমি কীভাবে আমার সি # প্রোগ্রামটি 50 মিলিসেকেন্ডে ঘুমাতে পারি?

এটি একটি সহজ প্রশ্ন মনে হতে পারে, তবে আমি একটি অস্থায়ী মস্তিষ্কের ব্যর্থতা মুহূর্ত করছি!


1
উত্তর সেখানে কাজ করে হিসাবে VB.NET পুনরায় ট্যাগ।
ডাঃফ্লয়েড 5

কোনও ড্রফ্লয়েড 5 নেই; VB.NET এ কাজ করে না, তাই না?
জাননি

16
আমি যদি ভিবি.নেট দলে থাকি, আমি যুক্ত করতাম; ভাষার পরবর্তী সংস্করণে একটি মন্তব্য চরিত্র হিসাবে ...
জোয়েল কোহোর্ন

4
আমি মনে করি ভিবি প্রোগ্রামাররা
সমতুল্যটি

ঠিক আছে, নিশ্চিত করার জন্য, এখন তাদের দরকার নেই।
সাইকোডাটা

উত্তর:


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

তবে মনে রাখবেন, মূল জিইউআই থ্রেডে এটি করা আপনার জিইউআইকে আপডেট করা থেকে বিরত রাখবে (এটি "আলস্য" বোধ করবে)

;এটিও VB.net এর জন্য কাজ করতে কেবল সরান ।


কোনও পদ্ধতিতে ঘুম ডাকার পরে, প্রোগ্রামটি কী নতুন পটভূমিতে (নতুন থ্রেড তৈরি না করে) চালিয়ে যেতে থাকবে? এছাড়াও, যদি আমি ঘুমকে একটি নতুন থ্রেডে কল করি তবে মূল থ্রেডটি কি কাজ চালিয়ে যাবে?
জে নিরগুদকার

@ জয়নির্গুডকর যে থ্রেডটিকে ঘুম বলে তা বন্ধ হয়ে যাবে। অন্যান্য থ্রেডগুলি প্রভাবিত হয় না।
ইসাক সাভো

এটি সঠিক হওয়ার নিশ্চয়তা নেই।
আকুমাবার্ন

150

মূলত কোনও প্রোগ্রামিং ভাষায় অপেক্ষা করার জন্য 3 টি পছন্দ রয়েছে:

  1. আলগা অপেক্ষা
    • নির্দিষ্ট সময়ের জন্য থ্রেড ব্লকগুলি কার্যকর করা (= প্রক্রিয়াকরণ শক্তি গ্রাস করে না)
    • অবরুদ্ধ / অপেক্ষার থ্রেডে কোনও প্রক্রিয়াজাতকরণ সম্ভব নয়
    • এত নির্ভুল নয়
  2. টাইট ওয়েটিং (টাইট লুপ নামেও পরিচিত)
    • প্রসেসর পুরো অপেক্ষার ব্যবধানের জন্য খুব ব্যস্ত থাকে (বাস্তবে, এটি একটি কোরের প্রসেসিং সময় সাধারণত 100% ব্যয় করে)
    • অপেক্ষা করার সময় কিছু ক্রিয়া সম্পাদন করা যেতে পারে
    • খুব সুনির্দিষ্ট
  3. পূর্ববর্তী 2 এর সংমিশ্রণ
    • এটি সাধারণত 1 এর প্রক্রিয়াকরণ দক্ষতা এবং 2 এর কিছু করার ক্ষমতা এবং নির্ভুলতা সমন্বয় করে।

১ এর জন্য - সি # তে আলগা অপেক্ষা:

Thread.Sleep(numberOfMilliseconds);

যাইহোক, উইন্ডোজ থ্রেড শিডিয়ুলারটি Sleep()প্রায় 15 মিমি হওয়ার সঠিকতা তৈরি করে (তাই ঘুম কেবল 20 মিমি অপেক্ষা করতে পারে, এমনকি ঠিক 1 মিমি অপেক্ষা করার জন্য নির্ধারিত হলেও)।

২ এর জন্য - সি # তে টাইট ওয়েটিং হ'ল:

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

আমরা DateTime.Nowসময় মাপার অন্যান্য উপায়গুলিও ব্যবহার করতে পারি তবে Stopwatchএটি আরও দ্রুত (এবং এটি সত্যই টাইট লুপে দৃশ্যমান হবে)।

৩. - সংমিশ্রণ:

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
}

এই কোডটি নিয়মিত 1 মিমি জন্য থ্রেড অবরোধ করে (বা ওএস থ্রেড সময়সূচির উপর নির্ভর করে কিছুটা বেশি), তাই প্রসেসর ব্লক করার সময়টির জন্য ব্যস্ত থাকে না এবং কোড প্রসেসরের 100% শক্তি গ্রহণ করে না। অন্যান্য প্রক্রিয়াকরণটি এখনও অবরুদ্ধকরণের মধ্যেই করা যায় (যেমন: ইউআই আপডেট করা, ইভেন্টগুলি পরিচালনা করা বা ইন্টারঅ্যাকশন / যোগাযোগের জিনিসগুলি করা)।


1
টাইমার এছাড়াও আগ্রহী হতে পারে
JonnyRaa

55

আপনি উইন্ডোজে ঘুমের সঠিক সময় নির্দিষ্ট করতে পারবেন না । তার জন্য আপনার একটি রিয়েল-টাইম ওএস দরকার। আপনি যা করতে পারেন তা সর্বনিম্ন ঘুমের সময় নির্দিষ্ট করে । তারপরে এটির পরে আপনার থ্রেডটি জাগ্রত করা শিডিয়ুলারের হাতে। এবং জিইউআই থ্রেডে কখনও কল করবেন না.Sleep()


44

যেহেতু এখন আপনার কাছে অ্যাসিঙ্ক / অপেক্ষার বৈশিষ্ট্য রয়েছে তাই 50 মিমি পর্যন্ত ঘুমানোর সর্বোত্তম উপায় হ'ল টাস্ক ব্যবহার করে eডেলা:

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

অথবা আপনি। নেট 4 টি লক্ষ্য করে নিচ্ছেন (ভিএস 2010 বা মাইক্রোসফ্টের জন্য অ্যাসিঙ্ক সিটিপি 3 সহ মাইক্রোসফট.বিসিএল.এসিঙ্ক) আপনার অবশ্যই ব্যবহার করতে হবে:

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

এইভাবে আপনি ইউআই থ্রেড অবরোধ করবেন না।


আপনি এই দেরীতে প্রতিক্রিয়া.ফ্লাশ করতে পারেন, যদি এটি লুপে থাকে?
তেওমান শিপাহি

না তুমি পারবে না. আমি বিশ্বাস করি একটি FlushAsyncসংস্করণ আছে।
টনি পেট্রিনা

6
একটি বিকল্প যার জন্য কোনও asyncঘোষণার দরকার নেই Task.Delay(50).Wait();
সেগুলি


14
Thread.Sleep(50);

থ্রেডটি নির্ধারিত সময়ের পরিমাণের জন্য অপারেটিং সিস্টেমের দ্বারা নির্বাহের জন্য নির্ধারিত হবে না। এই পদ্ধতিটি ওয়েটস্লিপজয়নকে অন্তর্ভুক্ত করতে থ্রেডের অবস্থার পরিবর্তন করে।

এই পদ্ধতিটি স্ট্যান্ডার্ড সিওএম এবং সেন্ডম্যাসেজ পাম্পিং করে না। আপনার যদি স্ট্রেডআড্রিট্রিবিউটযুক্ত থ্রেডে ঘুমানোর দরকার হয় তবে আপনি স্ট্যান্ডার্ড সিওএম এবং সেন্ডমেসেজ পাম্পিং করতে চান তবে জয়েন পদ্ধতির একটি ওভারলোড ব্যবহার করে বিবেচনা করুন যা একটি সময়সীমা ব্যবধান নির্দিষ্ট করে।

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);
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.