টাস্ক.ওয়েট বনাম অপেক্ষা করুন - ডেডলক?


194

আমি Task.Waitএবং এর মধ্যে পার্থক্যটি বেশ বুঝতে পারি না await

আমার একটি এএসপি.নেট ওয়েবএপিআই পরিষেবাতে নিম্নলিখিত ফাংশনগুলির অনুরূপ কিছু রয়েছে:

public class TestController : ApiController
{
    public static async Task<string> Foo()
    {
        await Task.Delay(1).ConfigureAwait(false);
        return "";
    }

    public async static Task<string> Bar()
    {
        return await Foo();
    }

    public async static Task<string> Ros()
    {
        return await Bar();
    }

    // GET api/test
    public IEnumerable<string> Get()
    {
        Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());

        return new string[] { "value1", "value2" }; // This will never execute
    }
}

কোথায় Getঅচলাবস্থা হবে।

এর কারণ কী হতে পারে? আমি যখন ব্লকিং ওয়েট না করে ব্যবহার করি তখন কেন এই সমস্যার কারণ হয় না await Task.Delay?


@ সার্ভে: সময় পেলেই আমি একটি রেপো নিয়ে ফিরে আসব। আপাতত এটি কাজ করে Task.Delay(1).Wait()যা যথেষ্ট ভাল।
রোন্যাগ করুন

2
Task.Delay(1).Wait()মূলত ঠিক একই জিনিস Thread.Sleep(1000)। প্রকৃত উত্পাদন কোডে এটি খুব কমই উপযুক্ত।
30:38

@ অ্যারন্যাগ: আপনার WaitAllঅচলাবস্থা সৃষ্টি করছে। আরও তথ্যের জন্য আমার উত্তরটিতে আমার ব্লগের লিঙ্কটি দেখুন। await Task.WhenAllপরিবর্তে আপনার ব্যবহার করা উচিত ।
স্টিফেন ক্লিয়ারি

6
@ronag কারণ আপনি ConfigureAwait(false)একটি একক থেকে কল Barবা Rosঅচলাবস্থা করবে না, কিন্তু কারণ আপনি একটি গণনীয় যে বেশী একটি তৈরি এবং তারপর ঐ সব অপেক্ষায় আছে, প্রথম বার দ্বিতীয় অচলাবস্থা হবে। আপনি যদি await Task.WhenAllসমস্ত কাজের জন্য অপেক্ষা না করে, যাতে আপনি এএসপি প্রসঙ্গে অবরুদ্ধ না হন, আপনি পদ্ধতিটি স্বাভাবিকভাবে ফিরে আসতে দেখবেন।
পরিবেশন করুন

2
@ronag আপনার অন্যান্য বিকল্প যোগ হবে .ConfigureAwait(false) গাছ আপ সব পথ পর্যন্ত আপনি অবরোধ যে ভাবে কিছুই নয় কি কখনো প্রধান প্রসঙ্গ পেতে চেষ্টা; যে কাজ করবে। অন্য বিকল্পটি একটি অভ্যন্তরীণ সিঙ্ক্রোনাইজেশন প্রসঙ্গটি স্পিন করা উচিত। লিঙ্ক । আপনি করা যদি Task.WhenAllএকটি ইন AsyncPump.Runএটা কার্যকরভাবে আপনাকে ছাড়াই পুরো জিনিস উপর অবরোধ করবে ConfigureAwaitযে কোন স্থানে, কিন্তু সম্ভবত একটি মাত্রাতিরিক্ত জটিল সমাধান যে।
পরিবেশন করুন

উত্তর:


268

Waitএবং await- একইরকম ধারণা অনুসারে - আসলে সম্পূর্ণ আলাদা।

Waitটাস্ক শেষ না হওয়া অবধি সিঙ্ক্রোনজলি ব্লক হয়ে যাবে। সুতরাং বর্তমান থ্রেডটি কার্যত সম্পূর্ণ হওয়ার অপেক্ষায় আক্ষরিক অর্থেই অবরুদ্ধ। একটি সাধারণ নিয়ম হিসাবে, আপনার " asyncসমস্ত উপায়ে ডাউন" ব্যবহার করা উচিত ; যে, asyncকোড ব্লক করবেন না । আমার ব্লগে, কীভাবে অ্যাসিক্রোনাস কোড ব্লক করা অচলাবস্থা সৃষ্টি করে তার বিশদটিতে আমি যাই ।

awaitটাস্ক শেষ না হওয়া পর্যন্ত অবিচ্ছিন্নভাবে অপেক্ষা করবে। এর অর্থ হ'ল বর্তমান পদ্ধতিটি "বিরাম দেওয়া" (এর রাজ্যটি ক্যাপচার করা হয়েছে) এবং পদ্ধতিটি তার আহ্বানকারীকে একটি অসম্পূর্ণ কাজ ফিরিয়ে দেয়। পরে, awaitঅভিব্যক্তিটি সম্পূর্ণ হওয়ার পরে, পদ্ধতির বাকী অংশটি ধারাবাহিকতা হিসাবে নির্ধারিত হয়।

আপনি একটি "সমবায় ব্লক" উল্লেখ করেছিলেন, যার মাধ্যমে আমি ধরে নিয়েছি যে আপনি কোনও Waitকাজটির অর্থ যা ওয়েটিং থ্রেডে চালিত হতে পারে mean এমন পরিস্থিতি রয়েছে যেখানে এটি ঘটতে পারে তবে এটি একটি অপ্টিমাইজেশন। এমন অনেকগুলি পরিস্থিতি রয়েছে যেখানে এটি ঘটতে পারে না , যেমন কাজটি যদি অন্য সময়সূচীর হয়ে থাকে, বা এটি ইতিমধ্যে শুরু হয়েছে বা যদি এটি একটি নন-কোড টাস্ক (যেমন আপনার কোড উদাহরণে: টাস্ক ইনলাইনটি Waitকার্যকর করতে পারে না Delayকারণ কোনও কোড নেই) এর জন্য).

আপনি আমার async/ awaitভূমিকা উপকারী হতে পারে ।


4
আমি মনে করি একটি ভুল বোঝাবুঝি আছে, Waitকাজ করে ফাইন awaitডেডলকস।
ronag

5
না, টাস্ক শিডিয়ুলার এটি করবে না। Waitথ্রেড অবরোধ করে, এবং এটি অন্যান্য জিনিসের জন্য ব্যবহার করা যায় না।
স্টিফেন ক্লিয়ারি

8
@ অ্যারন্যাগ আমার অনুমান যে আপনি কেবল আপনার পদ্ধতির নামগুলি মিশ্রিত করেছেন এবং আপনার অচলাবস্থাটি আসলে ব্লকিং কোডের সাথে হয়েছিল এবং কোডটির সাথে কাজ করেছে await। হয় যেটি, বা অচলাবস্থার সাথে সম্পর্কযুক্ত নয় এবং আপনি সমস্যার ভুল সনাক্ত করেছেন।
30:38

3
@ হেক্সটারমিনেটর: এটি ডিজাইনের মাধ্যমে - এটি ইউআই অ্যাপ্লিকেশনগুলির জন্য দুর্দান্ত কাজ করে তবে এএসপি.এনইটি অ্যাপ্লিকেশনগুলির পক্ষে উপায় অর্জন করার প্রবণতা রাখে না। এএসপি.নেট কোর এটিকে অপসারণের মাধ্যমে এটি ঠিক করেছে SynchronizationContext, সুতরাং একটি এএসপি.নেট কোরের অনুরোধে আর কোনও অচল লক নেই।
স্টিফেন ক্লিয়ারি

1
এমএসডিএন-তে এখানে বলা হয়েছে যে অপেক্ষারত পৃথক থ্রেড অ্যাসিনক্রোনাসে চালিত হয়। আমি কিছু অনুপস্থিত করছি? msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx
batmaci

6

আমি বিভিন্ন উত্স থেকে যা পড়েছি তার উপর ভিত্তি করে:

একটি awaitএক্সপ্রেশন থ্রেডটি চালাচ্ছে না যার উপর এটি চালানো হচ্ছে। পরিবর্তে, এটি অপেক্ষিত টাস্কটির asyncধারাবাহিকতা হিসাবে বাকী পদ্ধতির বাকীটিতে সাইন আপ করার জন্য কম্পাইলার তৈরি করে । নিয়ন্ত্রণ করুন তারপরে asyncপদ্ধতির কলারে ফিরে আসে । যখন টাস্কটি সম্পূর্ণ হয়, তখন এটি তার ধারাবাহিকতাটি আহ্বান করে এবং asyncযেখানে পদ্ধতিটি ছেড়ে দেওয়া হয়েছিল সেখানে পদ্ধতিটি কার্যকর করা আবার শুরু হয়।

একটি একক taskসম্পূর্ণ হওয়ার জন্য অপেক্ষা করতে, আপনি তার Task.Waitপদ্ধতিটি কল করতে পারেন । Waitএকক শ্রেণীর উদাহরণ সম্পাদন সম্পন্ন না করা অবধি পদ্ধতিতে একটি কল কলিং থ্রেডকে অবরুদ্ধ করে। Wait()কোনও কাজ শেষ না হওয়া অবধি নিঃশর্ত অপেক্ষা করার জন্য প্যারামিটারলেস পদ্ধতি ব্যবহার করা হয়। টাস্কটি Thread.Sleepদুটি সেকেন্ডের জন্য ঘুমানোর জন্য পদ্ধতিটি কল করে কাজের অনুকরণ করে ।

এই নিবন্ধটি একটি ভাল পড়া।


3
"তখন কি প্রযুক্তিগতভাবে ভুল হয় না? কেউ দয়া করে স্পষ্ট করতে পারেন?" - আমি কি স্পষ্ট করতে পারি; আপনি একটি প্রশ্ন হিসাবে জিজ্ঞাসা করছেন? (আপনি বনাম উত্তর জিজ্ঞাসা করছেন কিনা তা আমি কেবল পরিষ্কার করতে চাই)। যদি আপনি জিজ্ঞাসা করছেন: এটি আলাদা প্রশ্ন হিসাবে আরও ভাল কাজ করতে পারে; এটি একটি উত্তর হিসাবে এখানে নতুন প্রতিক্রিয়া জড়ো করার সম্ভাবনা কম
মার্ক Gravell

1
আমি প্রশ্ন উত্তরে সন্দেহ আমি এখানে ছিল জন্য পৃথক প্রশ্ন জিজ্ঞাসা আছে stackoverflow.com/questions/53654006/... ধন্যবাদ @MarcGravell। আপনি কি দয়া করে উত্তরের জন্য আপনার মোছা ভোটটি সরাতে পারেন?
আয়ুষমতী

"আপনি কি দয়া করে উত্তরের জন্য আপনার মোছা ভোটটি সরাতে পারেন?" - এটা আমার নয়; ♦ এর জন্য ধন্যবাদ, আমার দ্বারা এই জাতীয় কোনও ভোট তত্ক্ষণাত কার্যকর হয়ে যেত। তবে আমি মনে করি না যে এটি প্রশ্নের মূল পয়েন্টগুলির উত্তর দেয় যা অচলাবস্থার আচরণ সম্পর্কে।
মার্ক Gravell

-2

অন্যান্য উত্তরে কিছু গুরুত্বপূর্ণ তথ্য দেওয়া হয়নি:

"অ্যাসিঙ্ক ওয়েটিং" সিআইএল স্তরে আরও জটিল এবং এইভাবে মেমরি এবং সিপিইউ সময় ব্যয় করে।

অপেক্ষার সময়টি গ্রহণযোগ্য না হলে যে কোনও কাজ বাতিল হতে পারে।

"Async প্রতীক্ষিত" ক্ষেত্রে আমাদের কাছে এই জাতীয় কাজটি বাতিল বা এটি পর্যবেক্ষণ করার জন্য কোনও হ্যান্ডলার নেই।

টাস্ক ব্যবহার করা আরও নমনীয় হয় তবে "অ্যাসিঙ্ক অপেক্ষা"।

যে কোনও সিঙ্ক কার্যকারিতা অ্যাসিঙ্ক দ্বারা মোড়ানো দ্বারা পারে।

public async Task<ActionResult> DoAsync(long id) 
{ 
    return await Task.Run(() => { return DoSync(id); } ); 
} 

কোড ডুপ্লিকেশন ফট সিঙ্ক এবং অ্যাসিঙ্ক পদ্ধতি বা হ্যাক ব্যবহার করে কেন আমাকে অবশ্যই বাঁচতে হবে তা আমি দেখতে পাচ্ছি না।

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