টাস্ক.ডলে কখন ব্যবহার করবেন, কখন থ্রেড.স্লিপ ব্যবহার করবেন?


385

টাস্ক.ডেলি বনাম থ্রেড.স্লাইপ ব্যবহার করার জন্য এখানে কি কোনও নিয়ম (গুলি) রয়েছে ?

  • বিশেষত, অন্যটির চেয়ে কার্যকর / দক্ষ হওয়ার জন্য একটি ন্যূনতম মান প্রদান করা কি?
  • শেষ অবধি, যেহেতু Task.Delay একটি async / অপেক্ষার স্থিতিশীল মেশিনে প্রসঙ্গ-স্যুইচিংয়ের কারণ, তাই এটি ব্যবহার করার কি কোনও ওভারহেড আছে?

2
10 মিমি কম্পিউটার জগতে অনেকগুলি চক্র ...
ব্র্যাড ক্রিস্টি

এটি কত দ্রুত হওয়া উচিত? আপনার পারফরম্যান্সে কোন সমস্যা আছে?
এলবি

4
আমি মনে করি যে আরও প্রাসঙ্গিক প্রশ্নটি কোন প্রসঙ্গে আপনি এগুলির দুটি ব্যবহার করার ইচ্ছা রাখছেন? এই তথ্য ছাড়া সুযোগ খুব বিস্তৃত। কার্যকর / দক্ষ বলতে কী বোঝ? আপনি কি নির্ভুলতা, শক্তি দক্ষতা ইত্যাদি উল্লেখ করছেন? আমি এই বিষয়টির প্রসঙ্গে কী জানতে আগ্রহী।
জেমস ওয়ার্ল্ড

4
সর্বনিম্ন 15.625 ম্যাসি, ঘড়ির বিঘ্নিত হারের চেয়ে কম মানগুলির কোনও প্রভাব নেই। টাস্ক.ডেলা সর্বদা একটি সিস্টেম জ্বালিয়ে রাখে h থ্রেডিং.টাইমার, ঘুমের কোনও ওভারহেড নেই। আপনি যখন কোনও কোড লেখেন তখন ওভারহেড সম্পর্কে চিন্তা করবেন না।
হ্যান্স প্যাস্যান্ট

আমি এমন কিছু যা উল্লেখ করেছি না, তবে আমি মনে করি গুরুত্বপূর্ণ, তা হ'ল টাস্ক Dডেলা একটি বাতিলকরণ টোকেনকে সমর্থন করে, যার অর্থ আপনি বিলম্বকে বাধা দিতে পারেন, যদি আপনি উদাহরণস্বরূপ, একটি চক্র প্রক্রিয়াটি ধীর করতে ব্যবহার করেন to এর অর্থ হ'ল আপনি যখন এটি বাতিল করতে চান তখন আপনার প্রক্রিয়াটি দ্রুত প্রতিক্রিয়া জানাতে পারে। তবে আপনি থ্রেডের সাহায্যে একই অর্জন করতে পারেন S
দ্রোয়া

উত্তর:


369

Thread.Sleepআপনি যখন বর্তমান থ্রেডটি ব্লক করতে চান তখন ব্যবহার করুন ।

Task.Delayআপনি যখন বর্তমান থ্রেডটি ব্লক না করে লজিকাল বিলম্ব চান তখন ব্যবহার করুন ।

দক্ষতা এই পদ্ধতিগুলির সাথে সবচেয়ে বেশি উদ্বেগ হওয়া উচিত নয়। তাদের প্রাথমিক রিয়েল-ওয়ার্ল্ড ব্যবহার আই / ও ক্রিয়াকলাপগুলির জন্য পুনরায় চেষ্টা করা টাইমার হিসাবে রয়েছে, যা সেকেন্ডের পরিবর্তে মিলি সেকেন্ডের চেয়ে বেশি হয়।


3
এটি একই প্রাথমিক ব্যবহারের কেস: একটি পুনরায় চেষ্টা করুন টাইমার।
স্টিফেন ক্লিয়ারি

4
বা যখন আপনি কোনও প্রধান লুপে সিপিইউ চিবিয়ে নিতে চান না।
এডি পার্কার

5
@ রইনিমির: না। "অন্য থ্রেড" নেই। অভ্যন্তরীণভাবে, এটি একটি টাইমার দিয়ে প্রয়োগ করা হয়েছে।
স্টিফেন ক্লিয়ারি

20
দক্ষতা সম্পর্কে চিন্তা না করার পরামর্শটি অ-পরামর্শযুক্ত। Thread.Sleepবর্তমান থ্রেডটি ব্লক করে দেবে যা প্রসঙ্গের স্যুইচের কারণ। যদি আপনি কোনও থ্রেড পুল ব্যবহার করেন তবে এটির ফলে একটি নতুন থ্রেড বরাদ্দও হতে পারে। উভয় ক্রিয়াকলাপগুলি বেশ ভারী, যদিও Task.Delayইত্যাদির দ্বারা সরবরাহিত সমবায় মাল্টি-টাস্কিং এগুলি ওভারহেডের সমস্ত এড়ানো, সর্বাধিকতর থ্রুপুট, বাতিলকরণের অনুমতি প্রদান এবং ক্লিনার কোড সরবরাহ করার জন্য ডিজাইন করা হয়েছে।
করিলিয়ান

2
onesi: I would use সিঙ্ক্রোনাস পদ্ধতির ভিতরে অপেক্ষা করতে লুকাক্রিমি থ্রেড.স্লিপ তবে আমি প্রযোজনা কোডে কখনও এটি করি না; আমার অভিজ্ঞতায়, Thread.Sleepআমি প্রত্যক্ষটি প্রত্যেকে দেখেছি কোনওরকম ডিজাইন ইস্যুর সূচক হয়েছে যা সঠিকভাবে ঠিক করা দরকার।
স্টিফেন ক্লিয়ারি

243

Task.Delayএবং এর মধ্যে সবচেয়ে বড় পার্থক্য Thread.Sleepহ'ল এটি Task.Delayঅ্যাসিঙ্ক্রোনালি চালানো। এটি Task.Delayসিঙ্ক্রোনাস কোড ব্যবহার করার কোনও মানে হয় না । Thread.Sleepঅ্যাসিক্রোনাস কোড ব্যবহার করা খুব খারাপ ধারণা ।

সাধারণত আপনি কীওয়ার্ডটি Task.Delay() দিয়ে কল করবেন await:

await Task.Delay(5000);

বা, যদি আপনি বিলম্বের আগে কিছু কোড চালাতে চান:

var sw = new Stopwatch();
sw.Start();
Task delay = Task.Delay(5000);
Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
await delay;

অনুমান করুন এটি কি মুদ্রণ করবে? 0.0070048 সেকেন্ডের জন্য চলছে। পরিবর্তে আমরা যদি await delayউপরের Console.WriteLineস্থানটি সরিয়ে ফেলি তবে এটি চলমানটি 5.0020168 সেকেন্ডের জন্য মুদ্রণ করবে।

এর সাথে পার্থক্যটি দেখুন Thread.Sleep:

class Program
{
    static void Main(string[] args)
    {
        Task delay = asyncTask();
        syncCode();
        delay.Wait();
        Console.ReadLine();
    }

    static async Task asyncTask()
    {
        var sw = new Stopwatch();
        sw.Start();
        Console.WriteLine("async: Starting");
        Task delay = Task.Delay(5000);
        Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
        await delay;
        Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds);
        Console.WriteLine("async: Done");
    }

    static void syncCode()
    {
        var sw = new Stopwatch();
        sw.Start();
        Console.WriteLine("sync: Starting");
        Thread.Sleep(5000);
        Console.WriteLine("sync: Running for {0} seconds", sw.Elapsed.TotalSeconds);
        Console.WriteLine("sync: Done");
    }
}

এটি কী মুদ্রণ করবে তা ভবিষ্যদ্বাণী করার চেষ্টা করুন ...

ASYNC: শুরু হচ্ছে
জন্য 0.0070048 সেকেন্ড রানিং: ASYNC
শুরু: সিঙ্ক
ASYNC: 5.0119008 সেকেন্ডের জন্য চালনা
ASYNC: সম্পন্ন
সিঙ্ক: 5.0020168 সেকেন্ডের জন্য চালনা
সিঙ্ক: সম্পন্ন

এছাড়াও, এটি লক্ষ্য করা আকর্ষণীয় যে Thread.Sleepএটি আরও বেশি নির্ভুল, এমএস যথার্থতা আসলেই কোনও সমস্যা নয়, তবে Task.Delay15-30 মিমি ন্যূনতম নিতে পারে। উভয় ফাংশনগুলিতে ওভারহেড তাদের যে পরিমাণ এমএস নির্ভুলতার সাথে তুলনা করা হয় তা ন্যূনতম হয় ( Stopwatchআপনার আরও কিছু সঠিকের প্রয়োজন হলে ক্লাস ব্যবহার করুন )। Thread.Sleepএখনও আপনার থ্রেডটি বেঁধে রাখুন, Task.Delayঅপেক্ষা করার সময় অন্য কাজ করতে এটি ছেড়ে দিন।


15
কেন এটি "থ্রেড ব্যবহার করা খুব খারাপ ধারণা? অ্যাসিঙ্ক্রোনাস কোডে ঘুমান"?
সূর্যমুখী

69
@ সুনসাইড অ্যাসিঙ্ক কোডের অন্যতম প্রধান সুবিধা হ'ল ব্লকিং কলগুলি এড়িয়ে একটি থ্রেডকে একবারে একাধিক কাজে কাজ করার অনুমতি দেওয়া। এটি বিশাল পরিমাণে পৃথক থ্রেডের প্রয়োজনীয়তা এড়ায় এবং একটি থ্রেডপুলকে একবারে বহু অনুরোধগুলি সরবরাহ করতে দেয়। তবে, প্রদত্ত যে অ্যাসিঙ্ক কোডটি সাধারণত থ্রেডপুলে চলে, অকারণে একটি একক থ্রেডকে ব্লক Thread.Sleep()করে পুরো থ্রেড গ্রহণ করে যা অন্যথায় অন্যত্র ব্যবহৃত হতে পারে। থ্রেড.স্লিপ () দিয়ে যদি অনেকগুলি কাজ চালানো হয় তবে সমস্ত থ্রেডপুলের থ্রেড ক্লান্ত করার এবং কর্মক্ষমতা মারাত্মকভাবে বাধা দেওয়ার উচ্চ সম্ভাবনা রয়েছে।
রায়ান

1
এটা নাও. asyncএগুলি ব্যবহারের জন্য উত্সাহিত হওয়ায় আমি পদ্ধতিগুলির অর্থে অ্যাসিক্রোনাস কোডের ধারণাটি অনুপস্থিত । Thread.Sleep()থ্রেডপুলের থ্রেডে চালানো এটি কেবল একটি খারাপ ধারণা , সাধারণভাবে খারাপ ধারণা নয়। সর্বোপরি, TaskCreationOptions.LongRunning(নিরুৎসাহিত হলেও) Task.Factory.StartNew()রুটে যাওয়ার সময় সেখানে রয়েছে।
সূর্যমুখী

6
kudos await wait
এরিক

2
@ রেহেন এটির নথি Tasl.Delayযা সিস্টেম টাইমার ব্যবহার করে। যেহেতু "সিস্টেম ঘড়ি" একটি ধ্রুবক হারে "টিক্স" দেয়। ", সিস্টেম টাইমারটির টিক স্পিডটি প্রায় 16 মিমি, আপনি যে কোনও বিলম্বের জন্য অনুরোধ করেছেন প্রথম ঘণ্টায় অফসেটের পরে সিস্টেম ঘড়ির বেশ কয়েকটি টিক্সকে গোল করে দেবে" টিক্। উপর MSDN ডকুমেন্টেশন দেখুন Task.Delay docs.microsoft.com/en-us/dotnet/api/... এবং মন্তব্য নিচে স্ক্রোল করুন।
ডরাস

28

যদি বর্তমান থ্রেডটি মারা যায় এবং আপনি ব্যবহার করেন Thread.Sleepএবং এটি কার্যকর হয় তবে আপনি একটি পেতে পারেন ThreadAbortException। সঙ্গে Task.Delayআপনি সবসময় এমন একটি বাতিলের টোকেন প্রদান করতে পারেন এবং সুন্দরভাবে এটা হত্যা। আমি একটাই কারণ বেছে নিতে পারি Task.Delay। দেখতে http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx

আমিও সম্মত হই যে এই ক্ষেত্রে দক্ষতা সর্বোচ্চ নয়।


2
ধরে আমরা নিম্নলিখিত অবস্থা করেছেন: await Task.Delay(5000)। আমি যখন টাস্কটি পেয়েছি তখন আমি তাকে মেরে ফেলি TaskCanceledException(এবং এটি দমন করি) তবে আমার থ্রেডটি এখনও জীবিত। ঝরঝরে! :)
অ্যালেক্সমেলউ

24

আমি কিছু যুক্ত করতে চাই আসলে, Task.Delayএকটি টাইমার ভিত্তিক অপেক্ষা প্রক্রিয়া। আপনি যদি উত্সটি দেখেন তবে আপনি এমন কোনও Timerশ্রেণীর রেফারেন্স পাবেন যা দেরি করার জন্য দায়ী। অন্যদিকে স্রোতে Thread.Sleepপ্রকৃত সূত্রটি আসলে ঘুমিয়ে তোলে, আপনি কেবল একটি থ্রেড অবরুদ্ধ করছেন এবং নষ্ট করছেন। অ্যাসিঙ্ক প্রোগ্রামিং মডেলটিতে আপনাকে Task.Delay()কিছুটা দেরী হওয়ার পরে কিছুটা (ধারাবাহিকতা) চাইলে সর্বদা ব্যবহার করা উচিত ।


'টাস্কের অপেক্ষায় থাকুন। ডেলা ()' টাইমারটির মেয়াদ শেষ হওয়া অবধি 100% সাফ হওয়া পর্যন্ত থ্রেডটিকে অন্যান্য কাজ করতে মুক্ত করে। তবে যদি পদ্ধতিটি 'অ্যাসিঙ্ক' দিয়ে উপসর্গ করা না হয় তবে আমি যদি অপেক্ষা করতে পারি না তবে কী হবে? তারপরে আমি কেবল 'টাস্ক.ডেলি ()' কল করতে পারি। যে ক্ষেত্রে থ্রেড এখনো অবরুদ্ধ করা হয়েছে কিন্তু আমি বিলম্ব () বাতিল করার সুবিধা । এটা কি ঠিক?
এরিক স্ট্রোইকেন

5
@ এরিক স্ট্রোইকেন আপনি থ্রেড এবং টাস্ক উভয়তেই বাতিল টোকেন পাস করতে পারেন। Task.Delay ()। অপেক্ষা করুন () ব্লক হয়ে যাবে, যখন Task.Delay () কেবল অপেক্ষা না করে ব্যবহার করা হলে টাস্কটি তৈরি করে। সেই কাজটি নিয়ে আপনি যা করেন তা আপনার উপর নির্ভর করে তবে থ্রেড অবিরত রয়েছে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.