ওয়েটআল বনাম যখন সমস্ত


333

Async সিটিপি Task.WaitAll()এবং এর মধ্যে পার্থক্য কী Task.WhenAll()? বিভিন্ন ব্যবহারের ক্ষেত্রে চিত্রিত করতে আপনি কিছু নমুনা কোড সরবরাহ করতে পারেন?

উত্তর:


503

Task.WaitAll সবকিছু শেষ না হওয়া অবধি বর্তমান থ্রেড অবরোধ করে।

Task.WhenAllএকটি কাজ প্রদান করে যা সবকিছু শেষ না হওয়া পর্যন্ত অপেক্ষা করার ক্রিয়াকে প্রতিনিধিত্ব করে।

এর অর্থ একটি অ্যাসিঙ্ক পদ্ধতি থেকে আপনি ব্যবহার করতে পারেন:

await Task.WhenAll(tasks);

... যার অর্থ সমস্ত কিছু শেষ হয়ে গেলে আপনার পদ্ধতি অব্যাহত থাকবে, তবে আপনি যতক্ষণ না থেমে থ্রেড বেঁধে রাখবেন।


2
অনেক পাঠ করা হলে পরে এটা পরিষ্কার ASYNC কিছুই থ্রেড কি আছে যে blog.stephencleary.com/2013/11/there-is-no-thread.html
ভিন্স Panuccio

7
@ ভিনস: আমি মনে করি "থ্রেডগুলির সাথে কিছুই করার নেই" একটি অত্যুক্তি বিবরণ, এবং অ্যাসিঙ্ক ক্রিয়াকলাপগুলি থ্রেডের সাথে কীভাবে যোগাযোগ করে তা বোঝা গুরুত্বপূর্ণ।
জন স্কিটি

6
@ কেভিনবুই: না, এটি এটিকে অবরুদ্ধ করা উচিত নয় - এটি যে কাজটি করেছে তার জন্য অপেক্ষা করবে WhenAll, তবে এটি থ্রেড ব্লক করার মতো নয়।
জন স্কিটি

1
@ জোনস্কিট সম্ভবত এই দুজনের মধ্যে যথাযথ পার্থক্যটি আমার পক্ষে খুব সূক্ষ্ম is আপনি কি আমাকে (এবং সম্ভবত আমাদের বাকী) কিছু রেফারেন্সে নির্দেশ করতে পারেন যা পার্থক্যটি পরিষ্কার করে দেবে?
ক্যাটশোস 21

125
@ গুগল শো: সত্যই নয় - আমি এটি ইতিমধ্যে ব্যাখ্যা করার পাশাপাশি করেছি। আমি অনুমান করি যে আমি একটি উপমা দিতে পারব - এটি গ্রহণের পথে আদেশ দেওয়ার পরে দরজার পাশে দাঁড়িয়ে এটি পৌঁছানোর অপেক্ষায়, বনাম কোনও ব্যবস্থা নেওয়ার ব্যবস্থা করা, অন্যান্য জিনিসপত্র করা এবং তারপরে কুরিয়ার আসার সাথে সাথে দরজা খোলার মত ...
জন স্কেটি 1'15

50

যদিও জোনস্কিটের উত্তরটি একটি দুর্দান্ত উপায়ের মধ্যে পার্থক্যটি ব্যাখ্যা করে সেখানে আরও একটি পার্থক্য রয়েছে: ব্যতিক্রম হ্যান্ডলিং

Task.WaitAllএকটি ছোঁড়ার AggregateExceptionযখন কাজগুলো কোন ছোঁড়ার এবং আপনি সব নিক্ষিপ্ত ব্যতিক্রম পরীক্ষা করতে পারেন। awaitমধ্যে await Task.WhenAllunwraps AggregateExceptionএবং 'আয়' শুধুমাত্র প্রথম ব্যতিক্রম।

নীচের প্রোগ্রামটি যখন await Task.WhenAll(taskArray)আউটপুট দিয়ে সঞ্চালিত হয় নীচে হয়।

19/11/2016 12:18:37 AM: Task 1 started
19/11/2016 12:18:37 AM: Task 3 started
19/11/2016 12:18:37 AM: Task 2 started
Caught Exception in Main at 19/11/2016 12:18:40 AM: Task 1 throwing at 19/11/2016 12:18:38 AM
Done.

নীচের প্রোগ্রামটি যখন Task.WaitAll(taskArray)আউটপুট দিয়ে সম্পাদিত হয় নীচে হয় ।

19/11/2016 12:19:29 AM: Task 1 started
19/11/2016 12:19:29 AM: Task 2 started
19/11/2016 12:19:29 AM: Task 3 started
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 1 throwing at 19/11/2016 12:19:30 AM
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 2 throwing at 19/11/2016 12:19:31 AM
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 3 throwing at 19/11/2016 12:19:32 AM
Done.

কার্যক্রম:

class MyAmazingProgram
{
    public class CustomException : Exception
    {
        public CustomException(String message) : base(message)
        { }
    }

    static void WaitAndThrow(int id, int waitInMs)
    {
        Console.WriteLine($"{DateTime.UtcNow}: Task {id} started");

        Thread.Sleep(waitInMs);
        throw new CustomException($"Task {id} throwing at {DateTime.UtcNow}");
    }

    static void Main(string[] args)
    {
        Task.Run(async () =>
        {
            await MyAmazingMethodAsync();
        }).Wait();

    }

    static async Task MyAmazingMethodAsync()
    {
        try
        {
            Task[] taskArray = { Task.Factory.StartNew(() => WaitAndThrow(1, 1000)),
                                 Task.Factory.StartNew(() => WaitAndThrow(2, 2000)),
                                 Task.Factory.StartNew(() => WaitAndThrow(3, 3000)) };

            Task.WaitAll(taskArray);
            //await Task.WhenAll(taskArray);
            Console.WriteLine("This isn't going to happen");
        }
        catch (AggregateException ex)
        {
            foreach (var inner in ex.InnerExceptions)
            {
                Console.WriteLine($"Caught AggregateException in Main at {DateTime.UtcNow}: " + inner.Message);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Caught Exception in Main at {DateTime.UtcNow}: " + ex.Message);
        }
        Console.WriteLine("Done.");
        Console.ReadLine();
    }
}

13
সবচেয়ে বড় ব্যবহারিক পার্থক্যটি ব্যতিক্রম হ্যান্ডলিং। সত্যি? কারণ এটি আসলে সবচেয়ে বড় ব্যবহারিক পার্থক্য নয়। সবচেয়ে বড় ব্যবহারিক পার্থক্যটি হ'ল একটি হ'ল অ্যাসিঙ্ক এবং নন ব্লকিং যেখানে অন্যটি ব্লক করছে। এটি ব্যতিক্রমগুলি কীভাবে পরিচালনা করে তার চেয়ে অনেক বেশি গুরুত্বপূর্ণ।
লিয়াম

5
এই বিষয়টি চিহ্নিত করার জন্য ধন্যবাদ. আমি বর্তমানে যে দৃশ্যের সাথে কাজ করছি সে ক্ষেত্রে এই ব্যাখ্যাটি কার্যকর ছিল। সম্ভবত "বৃহত্তম ব্যবহারিক পার্থক্য" নয়, তবে অবশ্যই একটি ভাল কল out
উর্ক

ব্যতিক্রম হ্যান্ডলিং সবচেয়ে বড় ব্যবহারিক পার্থক্য হতে পারে await t1; await t2; await t3;বনামawait Task.WhenAll(t1,t2,t3);
frostshoxx

1
এই ব্যতিক্রম আচরণটি এখানে ডক্সের সাথে স্ববিরোধী নয় ( ডকস.মাইক্রোসফট.ফেন / ডটনেট / এপি / ৮ ) "সরবরাহিত কোনও কাজ যদি একটি ত্রুটিযুক্ত অবস্থায় সম্পূর্ণ হয় তবে প্রত্যাবর্তিত কার্যটিও একটি ত্রুটিযুক্ত অবস্থায় সম্পূর্ণ হবে , যেখানে এর ব্যতিক্রমগুলিতে সরবরাহিত প্রতিটি কাজ থেকে মোড়কযুক্ত ব্যতিক্রমগুলির সেটটির সংহতকরণ থাকবে।
দাসিথ উইজেস

1
আমি এটিকে একটি শৈল্পিক হিসাবে বিবেচনা করি await, দুটি পদ্ধতির মধ্যে পার্থক্য নয়। উভয়ই একটি প্রচার করে AggregateException, হয় সরাসরি নিক্ষেপ করে বা কোনও সম্পত্তি ( Task.Exceptionসম্পত্তি) এর মাধ্যমে।
থিওডর জোলিয়াস

20

পার্থক্যের উদাহরণ হিসাবে - যদি আপনার কোনও কাজ থাকে তবে ইউআই থ্রেড দিয়ে কিছু করে (উদাহরণস্বরূপ একটি কাজ যা স্টোরিবোর্ডে একটি অ্যানিমেশন উপস্থাপন করে) যদি আপনি Task.WaitAll()তখন ইউআই থ্রেডটি অবরুদ্ধ করে থাকেন এবং ইউআই কখনই আপডেট হয় না। আপনি যদি ব্যবহার করেন await Task.WhenAll()তবে ইউআই থ্রেডটি অবরুদ্ধ নয়, এবং ইউআই আপডেট করা হবে।


7

তারা কি করে:

  • অভ্যন্তরীণভাবে উভয়ই একই জিনিস করে।

পার্থক্য কি:

  • ওয়েটআল একটি ব্লকিং কল call
  • যখন সমস্ত - না - কোড চালানো চালিয়ে যাবে

যা ব্যবহার করুন যখন:

  • ফলাফল না থাকলে কখনই চালিয়ে যেতে পারবেন না অপেক্ষা করুন
  • যখন সমস্ত কখন কী অবহিত করা হবে, অবরুদ্ধ নয়

1
@ মার্টিনরোডস তবে আপনি যদি তাৎক্ষণিকভাবে অপেক্ষা না করেন তবে অন্য কোনও কাজ চালিয়ে যান এবং তারপরে অপেক্ষা করেন? WaitAllআমি বুঝতে পারছি বলে আপনার সেই সম্ভাবনা নেই ।
জেপ্পে

@ জেপ্পি আপনি অন্য কিছু কাজ করার Task.WaitAll পরে কি কলটির চেয়ে আলাদা করতে পারবেন না? মানে, আপনার কাজগুলি শুরু করার পরে এটি কল করার পরিবর্তে
পিএল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.