যদি অ্যাসিঙ্ক-অপেক্ষার কোনও অতিরিক্ত থ্রেড তৈরি না করে, তবে এটি কীভাবে অ্যাপ্লিকেশনগুলিকে প্রতিক্রিয়াশীল করে?


242

সময় এবং সময় আবার, আমি এটি দেখেছি যে ব্যবহার করে async- awaitকোন অতিরিক্ত থ্রেড তৈরি করে না। এটি বোঝা যায় না কারণ কম্পিউটারে একবারে 1 টিরও বেশি কাজ করার একমাত্র উপায়

  • প্রকৃতপক্ষে একাধিক জিনিস একসাথে করা (সমান্তরালভাবে নির্বাহ করা, একাধিক প্রসেসরের ব্যবহার করা)
  • কার্যগুলি নির্ধারিত করে এবং তাদের মধ্যে স্যুইচিংয়ের মাধ্যমে এটিকে সিমুলেট করে (কিছুটা A, খানিকটা বি, সামান্য A ইত্যাদি করুন)

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


17
IO কার্যগুলি সিপিইউযুক্ত নয় এবং সুতরাং কোনও থ্রেডের প্রয়োজন হয় না। অ্যাসিঙ্কের মূল বিষয় হ'ল আইও বাউন্ড টাস্কগুলির সময় থ্রেডগুলি ব্লক করা না।
juharr

24
@ জেডওয়েং: না, একেবারেই নয়। এমনকি এটি নতুন থ্রেড তৈরি করলেও, এটি একটি নতুন প্রক্রিয়া তৈরির থেকে খুব আলাদা।
জন স্কিটি

8
যদি আপনি কলব্যাক-ভিত্তিক অ্যাসিনক্রোনাস প্রোগ্রামিং বুঝতে থাকেন তবে কোনও থ্রেড তৈরি না করে আপনি কীভাবে await/ asyncকার্যকারিতা বুঝতে পারবেন ।
ব্যবহারকারী 253751

6
ঠিক না করা একটি আবেদন আরো প্রতিক্রিয়াশীল, কিন্তু এটি আপনার থ্রেড, যা অপ্রতিক্রিয়াশীল অ্যাপ্লিকেশন একটি সাধারণ কারণ ব্লক থেকে নিরুত্সাহিত নেই।
ওভেন

6
@ রাবারডাক: হ্যাঁ, এটি ধারাবাহিকতার জন্য থ্রেড পুল থেকে একটি থ্রেড ব্যবহার করতে পারে। তবে এটি ওপি এখানে যেভাবে কল্পনা করেছে তাতে থ্রেড শুরু করছে না - এটি এইরকম নয় যে এটি বলে যে "এই সাধারণ পদ্ধতিটি নিন, এখন এটি একটি পৃথক থ্রেডে চালান - সেখানে, এটি অ্যাসিঙ্ক।" এটি তার চেয়ে অনেক সূক্ষ্ম।
জন স্কিটি

উত্তর:


299

আসলে, অ্যাসিঙ্ক / প্রতীক্ষা যে জাদুকরী নয়। পুরো বিষয়টি বেশ বিস্তৃত তবে আপনার প্রশ্নের দ্রুত এবং সম্পূর্ণ পর্যাপ্ত উত্তরের জন্য আমি মনে করি আমরা পরিচালনা করতে পারি।

উইন্ডোজ ফর্ম অ্যাপ্লিকেশনে একটি সাধারণ বোতাম ক্লিক ইভেন্টটি সামলানো যাক:

public async void button1_Click(object sender, EventArgs e)
{
    Console.WriteLine("before awaiting");
    await GetSomethingAsync();
    Console.WriteLine("after awaiting");
}

আমি আপাতত যা ফিরিয়ে দিচ্ছে তা নিয়ে স্পষ্টভাবে কথা বলতে যাচ্ছি নাGetSomethingAsync । আসুন আমরা এটি বলি যে এটি 2 সেকেন্ড পরে সম্পূর্ণ হবে।

একটি traditionalতিহ্যবাহী, অ-আশ্রয়বিহীন, বিশ্বে আপনার বোতাম ক্লিক ইভেন্ট হ্যান্ডলারটি দেখতে এরকম কিছু দেখাবে:

public void button1_Click(object sender, EventArgs e)
{
    Console.WriteLine("before waiting");
    DoSomethingThatTakes2Seconds();
    Console.WriteLine("after waiting");
}

আপনি যখন ফর্মের বোতামটি ক্লিক করেন, অ্যাপ্লিকেশনটি প্রায় 2 সেকেন্ডের জন্য হিমায়িত হবে, যখন আমরা এই পদ্ধতিটি শেষ হওয়ার অপেক্ষা করব। যা হয় তা হ'ল "বার্তা পাম্প", মূলত একটি লুপ অবরুদ্ধ।

এই লুপটি ক্রমাগত উইন্ডোজকে জিজ্ঞাসা করে "" কেউ কি কিছু করেছে, যেমন মাউস সরিয়ে নিয়েছে, কোনও কিছুর উপর ক্লিক করেছে? আমার কি আবার কিছু রঙ করা দরকার? যদি তাই হয় তবে আমাকে বলুন! " এবং তারপরে সেই "কিছু" প্রক্রিয়া করে। এই লুপটি একটি বার্তা পেয়েছিল যা ব্যবহারকারী "বাটন 1" (বা উইন্ডোজ থেকে সমান ধরণের বার্তা) ক্লিক করেছেন এবং button1_Clickউপরে আমাদের পদ্ধতিটি কল করে শেষ করেছেন । এই পদ্ধতিটি ফিরে না আসা পর্যন্ত এই লুপটি এখন অপেক্ষা করে আটকে আছে। এটি 2 সেকেন্ড সময় নেয় এবং এই সময়ে কোনও বার্তা প্রক্রিয়াকরণ করা হয় না।

উইন্ডোজগুলির সাথে সম্পর্কিত বেশিরভাগ জিনিসগুলি বার্তাগুলি ব্যবহার করে করা হয়, যার অর্থ হ'ল যদি বার্তা লুপটি বার্তা পাম্প করা বন্ধ করে দেয়, এমনকি মাত্র এক সেকেন্ডের জন্যও, এটি ব্যবহারকারী দ্বারা দ্রুত লক্ষণীয় হয়। উদাহরণস্বরূপ, আপনি যদি নিজের প্রোগ্রামের শীর্ষে নোটপ্যাড বা অন্য কোনও প্রোগ্রাম সরিয়ে নিয়ে যান এবং তারপরে আবারও, আপনার প্রোগ্রামটিতে পেইন্ট বার্তাগুলির একটি ঝাঁকুনি প্রেরণ করা হয় যা উইন্ডোর কোন অঞ্চলটি হঠাৎ আবার দৃশ্যমান হয়ে উঠেছে তা নির্দেশ করে। যদি এই বার্তাগুলি প্রসেস করে এমন বার্তা লুপ যদি কোনও কিছুর জন্য অপেক্ষা করে, অবরুদ্ধ করে থাকে, তবে কোনও চিত্রকাজ করা হয়নি।

সুতরাং, যদি প্রথম উদাহরণে, async/awaitনতুন থ্রেড তৈরি না করে, এটি কীভাবে এটি করে?

ঠিক আছে, যা ঘটে তা হ'ল আপনার পদ্ধতিটি দুটি ভাগে বিভক্ত। এটি এই বিস্তৃত বিষয়গুলির মধ্যে একটি যা তাই আমি খুব বেশি বিশদে যাব না তবে এই দুটি জিনিসকে এই পদ্ধতিতে বিভক্ত করে বলাই যথেষ্ট:

  1. awaitকল করার সময় সহ সমস্ত কোডGetSomethingAsync
  2. সমস্ত কোড নিম্নলিখিত await

চিত্রণ:

code... code... code... await X(); ... code... code... code...

পুনর্বিন্যাস:

code... code... code... var x = X(); await X; code... code... code...
^                                  ^          ^                     ^
+---- portion 1 -------------------+          +---- portion 2 ------+

মূলত পদ্ধতিটি এভাবে চালায়:

  1. এটি সবকিছু সম্পাদন করে await
  2. এটি সেই GetSomethingAsyncপদ্ধতিটিকে কল করে , যা এটি করে এবং এটি এমন কিছু দেয় যা ভবিষ্যতে 2 সেকেন্ড পূর্ণ হবে

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

  3. কী- awaitওয়ার্ডটি কিছু চতুর সংকলক যাদুর সাথে একসাথে করে তা হ'ল এটি মূলত "ঠিক আছে, আপনি কি জানেন, আমি এখানে কেবল বোতাম ক্লিক ইভেন্ট হ্যান্ডলারটি থেকে ফিরে আসছি When আপনি যখন (যেমন হিসাবে থাকবেন, তবে আমরা জিনিসটি) পুনরায় অপেক্ষা করছেন) সমাপ্তির কাছাকাছি আসুন, আমাকে জানান কারণ আমার এখনও কার্যকর করতে কিছু কোড বাকী আছে "left

    আসলে এটি সিঙ্ক্রোনাইজেশন কনটেক্সট ক্লাসকে জানতে দেয় যে এটি সম্পন্ন হয়েছে, যা এই মুহূর্তে প্লেতে আসার আসল সিনক্রোনাইজেশন প্রসঙ্গে নির্ভর করে মৃত্যুদন্ড কার্যকর করার জন্য সারিবদ্ধ হবে। উইন্ডোজ ফর্ম প্রোগ্রামে ব্যবহৃত প্রসঙ্গ শ্রেণিটি ম্যাসেজের লুপটি পাম্প করছে এমন সারিটি ব্যবহার করে এটি সারি করবে।

  4. সুতরাং এটি বার্তা লুপটিতে ফিরে আসে, যা এখন উইন্ডোটি সরিয়ে নেওয়া, পুনরায় আকার দেওয়ার বা অন্য বোতামে ক্লিক করার মতো বার্তা পাম্প চালিয়ে যেতে বিনামূল্যে।

    ব্যবহারকারীর জন্য, ইউআই এখন আবার প্রতিক্রিয়াশীল, অন্যান্য বোতামের ক্লিকগুলিকে পুনরায় আকার দিচ্ছে এবং সবচেয়ে গুরুত্বপূর্ণভাবে, পুনরায় আঁকছে , যাতে এটি হিমায়িত হয় না।

  5. 2 সেকেন্ড পরে, আমরা যে বিষয়টিটির জন্য অপেক্ষা করছি এটি এখন সম্পূর্ণ হয় এবং এখন যা ঘটে তা হ'ল এটি (ভাল, সিঙ্ক্রোনাইজেশন প্রসঙ্গে) একটি বার্তাটিকে কাতারে রাখে যা বার্তা লুপটি দেখছে, "আরে, এর জন্য আমি আরও কিছু কোড পেয়েছি আপনি কার্যকর করতে ", এবং এই কোডটি অপেক্ষার পরে সমস্ত কোড ।
  6. বার্তাটির লুপটি সেই বার্তায় পৌঁছে গেলে, এটি মূলত সেই পদ্ধতিটি "পুনরায় প্রবেশ" করবে যেখানে এটি ছেড়ে গেছে, ঠিক এর পরে awaitএবং বাকি পদ্ধতিটি কার্যকর করে চালিয়ে যাওয়া। নোট করুন যে এই কোডটি আবার বার্তা লুপ থেকে কল করা হয়েছে তাই যদি এই কোডটি async/awaitসঠিকভাবে ব্যবহার না করে দীর্ঘায়িত কিছু করা হয়ে থাকে তবে এটি আবার বার্তা লুপটিকে অবরুদ্ধ করবে

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


ঠিক আছে, সুতরাং GetSomethingAsync2 সেকেন্ডের মধ্যে সম্পূর্ণ হবে যে থ্রেড স্পিন যদি ? হ্যাঁ, তাহলে অবশ্যই খেলতে একটি নতুন থ্রেড রয়েছে। এই থ্রেডটি যদিও এই পদ্ধতির async-ness এর কারণে নয়, কারণ এই পদ্ধতির প্রোগ্রামার অ্যাসিঙ্ক্রোনাস কোড প্রয়োগের জন্য একটি থ্রেড বেছে নিয়েছিল। প্রায় সমস্ত অ্যাসিক্রোনাস আই / ও কোনও থ্রেড ব্যবহার করে না , তারা বিভিন্ন জিনিস ব্যবহার করে। async/await নিজেরাই নতুন থ্রেড স্পিন করবেন না তবে স্পষ্টতই থ্রেড ব্যবহার করে "আমরা অপেক্ষা করি" জিনিসগুলি প্রয়োগ করা যেতে পারে।

.NET- এ এমন অনেকগুলি বিষয় রয়েছে যা অগত্যা তাদের নিজের উপর কোনও থ্রেড স্পিন করে না তবে তারা এখনও অ্যাসিনক্রোনাস হয়:

  • ওয়েব অনুরোধগুলি (এবং আরও অনেকগুলি নেটওয়ার্ক সম্পর্কিত জিনিস যা সময় নেয়)
  • অ্যাসিঙ্ক্রোনাস ফাইল পড়া এবং লেখা
  • এবং আরো অনেক, একটি ভাল লক্ষণ যদি প্রশ্নে বর্গ / ইন্টারফেস সংঙ্ক্রান্ত নাম দিয়েছে পদ্ধতি SomethingSomethingAsyncবা BeginSomethingএবং EndSomethingসেখানে একটি ব্যাপার IAsyncResultজড়িত।

সাধারণত এই জিনিসগুলি হুডের নিচে থ্রেড ব্যবহার করে না।


ঠিক আছে, তাই আপনি কিছু "ব্রড টপিক স্টাফ" চান?

আচ্ছা, আমাদের বোতাম ক্লিক সম্পর্কে রজলিনকে জিজ্ঞাসা করুন :

রোজলিন চেষ্টা করুন

আমি এখানে পূর্ণ উত্পন্ন শ্রেণিতে লিঙ্ক করতে যাচ্ছি না তবে এটি বেশ সুন্দর বিষয়।


11
সুতরাং এটি মূলত ওপি " টাস্ক সময়সূচী এবং তাদের মধ্যে স্যুইচিংয়ের মাধ্যমে সমান্তরাল সম্পাদনের সিমুলেটিং " হিসাবে বর্ণনা করেছে , তাই না?
বার্গি

4
পছন্দ করেছেন মৃত্যুদন্ড কার্যকরভাবে সমান্তরাল - অ্যাসিঙ্ক্রোনাস আই / ও টাস্ক চলমান রয়েছে এবং এগিয়ে যাওয়ার জন্য কোনও থ্রেডের প্রয়োজন নেই (এটি এমন একটি বিষয় যা উইন্ডোজ ঘুরে আসার অনেক আগে থেকেই ব্যবহৃত হয়েছিল - এমএস ডস অ্যাসিঙ্ক্রোনাস আই / ও ব্যবহার করেছেন, যদিও এটি হয়নি) মাল্টি-থ্রেডিং রয়েছে!)। অবশ্যই আপনি যেভাবে এটি বর্ণনা করেছেন সেভাবে ব্যবহার করা await যেতে পারে, তবে সাধারণত তা হয় না। কেবল কলব্যাকগুলি নির্ধারিত হয় (থ্রেড পুলে) - কলব্যাক এবং অনুরোধের মধ্যে কোনও থ্রেডের প্রয়োজন হয় না।
লুয়ান

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

6
@ লাসেভি.কার্লসেন - আমি আপনার দুর্দান্ত উত্তরটি খাচ্ছি, তবে আমি এখনও একটি বিবরণে ঝুলছি। আমি বুঝেছি যে ইভেন্ট হ্যান্ডলারটি অস্তিত্ব রয়েছে, যেমন চতুর্থ ধাপে, যা বার্তা পাম্পটিকে পাম্প চালিয়ে যেতে সক্ষম করে, তবে "থেমেড যে দুটি সেকেন্ড লাগে" পৃথক থ্রেডে না থাকলে কখন এবং কোথায় চালানো যেতে পারে? যদি এটি ইউআই থ্রেডে নির্বাহ করা হয়, তবে এটি কার্যকর করার সময় বার্তা
পাম্পটিকে

3
আমি বার্তা পাম্প সঙ্গে আপনার ব্যাখ্যা পছন্দ। কনসোল অ্যাপ্লিকেশন বা ওয়েব সার্ভারের মতো কোনও বার্তা পাম্প না থাকলে আপনার ব্যাখ্যা কীভাবে আলাদা হয়? কোনও পদ্ধতির পুনরায় প্রবেশ কীভাবে সম্ভব?
পুচাকজ

95

আমি আমার ব্লগ পোস্টে এটি পুরোপুরিভাবে ব্যাখ্যা করেছি সেখানে কোনও থ্রেড নেই

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

অপারেশনটি একবার ফ্লাইটে চলে যাওয়ার পরে, সিপিইউ করার কোনও কাজ নেই, এবং কোনও থ্রেড নেই।


কেবল এটি পরিষ্কার করার জন্য .. অ্যাসিঙ্ক-অপেক্ষার ব্যবহারের সময় কী ঘটে যায় তার উচ্চ স্তরের বিষয়টি আমি বুঝতে পারি। কোনও থ্রেড তৈরির বিষয়ে নয় - কেবলমাত্র ডি / ডি / র অনুরোধগুলিতে কোনও থ্রেড নেই যা আপনি বলেছিলেন তাদের নিজস্ব প্রসেসর রয়েছে যা অনুরোধটি নিজে পরিচালনা করে? আমরা কি ধরে নিতে পারি যে সমস্ত আই / ও অনুরোধগুলি এই জাতীয় স্বতন্ত্র প্রসেসরের উপর নির্ভর করে হস্তান্তরিত হয় যার অর্থ টাস্ক ব্যবহার CP
যোনাতন নীড়

@ যোনাতনির: এটি কেবল আলাদা প্রসেসর সম্পর্কে নয়; যে কোনও ধরণের ইভেন্ট-চালিত প্রতিক্রিয়া স্বভাবতই অ্যাসিনক্রোনাস। Task.Runসিপিইউ-আবদ্ধ ক্রিয়াকলাপের জন্য সবচেয়ে উপযুক্ত , তবে এটির অন্যান্য কয়েকটি ব্যবহারও রয়েছে।
স্টিফেন ক্লিয়ারি 14

1
আমি আপনার নিবন্ধটি পড়া শেষ করেছি এবং এখনও বেসিক কিছু বুঝতে পারি না কারণ আমি ওএসের নিম্ন স্তরের প্রয়োগের সাথে সত্যই পরিচিত নই। আপনি যেখানে লিখেছেন সেখানে আমি যা পেয়েছি তা পেয়েছি: "লেখার কাজটি এখন" ফ্লাইটে "How । সুতরাং যদি কোনও থ্রেড না থাকে, তবে থ্রেড না থাকলে অপারেশনটি কীভাবে নিজেই সম্পন্ন হবে?
যোনাতন নীর

6
এটি হাজার হাজার ব্যাখ্যায় হারিয়ে যাওয়া টুকরো !!! আই / ও ক্রিয়াকলাপের সাথে ব্যাকগ্রাউন্ডে কেউ কাজ করছেন actually এটি কোনও থ্রেড নয় বরং আরও একটি ডেডিকেটেড হার্ডওয়্যার উপাদান যা কাজ করছে!
the_dark_destructor

2
@ প্রব্বুইরাসিংহে: সংকলক একটি কাঠামো তৈরি করে যা রাজ্য এবং স্থানীয় ভেরিয়েবলগুলিকে ধারণ করে। যদি কোনও অপেক্ষা অপেক্ষা করতে হয় (যেমন, তার আহ্বানে ফিরে আসুন), সেই স্ট্রাক্ট বাক্সযুক্ত এবং গাদা হয়ে থাকে the
স্টিফেন ক্লিয়ারি

87

কম্পিউটার একবারে ১ টিরও বেশি কাজ করছে বলে মনে হতে পারে (1) আসলে এক সাথে 1 টির বেশি কাজ করা, (২) কাজের সময়সূচী তৈরি করে এবং এগুলির মধ্যে স্যুইচিংয়ের মাধ্যমে এটিকে সিমুলেট করে। সুতরাং যদি অ্যাসিঙ্ক-প্রতীক্ষা তাদের কোনওটিই করে না

এটি প্রত্যাশা না যে দুটির কেউই করে না । মনে রাখবেন, এর উদ্দেশ্য awaitহ'ল সিঙ্ক্রোনাস কোডটিকে ম্যাজিকালি অ্যাসিঙ্ক্রোনাস না করাঅ্যাসিঙ্ক্রোনাস কোডে কল করার সময় আমরা সিঙ্ক্রোনাস কোড লেখার জন্য যে একই কৌশল ব্যবহার করি তা ব্যবহারের জন্য এটি সক্ষম করা । ওয়েট হ'ল উচ্চ বিলম্বিত ক্রিয়াকলাপগুলি এমন কোডের মতো দেখায় যা নিম্ন প্রক্ষেপণ অপারেশন ব্যবহার করে । এই উচ্চ বিলম্বিত অপারেশনগুলি থ্রেডে থাকতে পারে, তারা বিশেষ উদ্দেশ্যে হার্ডওয়্যারে থাকতে পারে, তারা তাদের কাজটি সামান্য টুকরো টুকরো টুকরো করে ছুঁড়ে মারছে এবং পরে ইউআই থ্রেড দ্বারা প্রক্রিয়াজাতকরণের জন্য বার্তা কাতারে রাখছে। তারা অ্যাসিক্রোনারি অর্জনের জন্য কিছু করছে , তবে তারাযেগুলি এটি করছে are ওয়েভ আপনাকে কেবল সেই অ্যাসিনক্রোনির সুবিধা নিতে দেয়।

এছাড়াও, আমি মনে করি আপনি একটি তৃতীয় বিকল্প মিস করছেন। আমরা বৃদ্ধ লোকেরা - বাচ্চাদের আজ তাদের র‌্যাপ সংগীতটি আমার লন ইত্যাদি বন্ধ করে দেওয়া উচিত - ১৯৯০ এর দশকের গোড়ার দিকে উইন্ডোজের জগতটি মনে রাখুন। এখানে কোনও মাল্টি-সিপিইউ মেশিন নেই এবং কোনও থ্রেড শিডিয়ুলার ছিল না। আপনি একই সাথে দুটি উইন্ডোজ অ্যাপ্লিকেশন চালনা করতে চেয়েছিলেন, আপনাকে ফলন করতে হয়েছিল । মাল্টিটাস্কিং ছিল সমবায় । ওএস একটি প্রক্রিয়াটি বলে যে এটি চালানো হয়ে যায়, এবং যদি এটি খারাপ ব্যবহার করা হয় তবে এটি অন্য সমস্ত প্রক্রিয়াগুলি পরিবেশন করা থেকে বিরত থাকে। ফলন না হওয়া পর্যন্ত এটি চলতে থাকে এবং পরের বার ওএস হাতগুলি এটিতে ফিরে নিয়ন্ত্রণ করে কোথায় চলে যায় তা কীভাবে নিতে হবে তা জানতে হবে। একক থ্রেডযুক্ত অ্যাসিনক্রোনাস কোড অনেকটা এর মতো, "প্রত্যাশার" পরিবর্তে "অপেক্ষা" করে। অপেক্ষার অর্থ "আমি এখানে ছেড়েছি বলে আমি স্মরণ করছি এবং অন্য কাউকে কিছুক্ষণ দৌড়াতে দাও; আমি যে টাস্কটির অপেক্ষায় রয়েছি তা শেষ হলে আমাকে আবার ফোন করুন এবং আমি যেখানে রেখেছি সেখানেই উঠব pick" আমি মনে করি যে আপনি কীভাবে অ্যাপ্লিকেশনগুলিকে আরও প্রতিক্রিয়াশীল করে তুলতে পারবেন, ঠিক যেমনটি উইন্ডোজ 3 দিনের মতো হয়েছিল।

যে কোনও পদ্ধতিতে কল করার অর্থ পদ্ধতিটি সম্পূর্ণ হওয়ার অপেক্ষায়

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

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


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

2
@ জ্যাব: একেবারে। জেনারেটরগুলিকে সি # তে "পুনরায় ব্লক" বলা হয় এবং yieldকীওয়ার্ডটি ব্যবহার করুন । asyncসি # তে উভয় পদ্ধতি এবং পুনরুক্তি হ'ল এক প্রকারের কর্টিন , যা কোনও ফাংশনের জন্য সাধারণ শব্দ যা জানে যে কীভাবে তার পুনরায় পুনঃস্থাপনের জন্য তার বর্তমান অপারেশন স্থগিত করতে হয়। বেশ কয়েকটি ভাষায় এই দিনগুলিতে কর্টাইন বা কর্টিনের মতো নিয়ন্ত্রণ প্রবাহ রয়েছে।
এরিক লিপার্ট

1
ফলনের উপমাটি একটি ভাল - এটি একটি প্রক্রিয়ার মধ্যে সমবায় মাল্টিটাস্কিং (এবং এর ফলে সিস্টেম-ব্যাপী সমবায় মাল্টিটাস্কিংয়ের সিস্টেমের স্থিতিশীলতার বিষয়গুলি এড়ানো)
ব্যবহারকারী 253751

3
আমি মনে করি আইও-র জন্য ব্যবহৃত হচ্ছে "সিপিইউ ইন্টারপ্রেটস" ধারণাটি প্রচুর পরিমাণে মডেম "প্রোগ্রামার" সম্পর্কে জানে না, তাই তারা মনে করে যে থ্রেডের প্রতিটি বিওটির জন্য অপেক্ষা করা দরকার।
ইয়ান রিংরোজ

WebClient এর @EricLippert এসিঙ্ক পদ্ধতি আসলে অতিরিক্ত থ্রেড তৈরি করে, এখানে দেখতে stackoverflow.com/questions/48366871/...
KevinBui

28

আমি সত্যিই খুশি যে এই প্রশ্নটি কেউ জিজ্ঞাসা করেছেন, কারণ দীর্ঘ সময় ধরে আমি বিশ্বাস করি যে থ্রেডগুলি সম্মতিযুক্ত হওয়া দরকার। আমি যখন প্রথম ইভেন্টের লুপগুলি দেখেছি তখন আমি ভেবেছিলাম এগুলি একটি মিথ্যা were আমি নিজেকে ভেবেছিলাম "এই কোডটি যদি একক থ্রেডে চালিত হয় তবে এই কোডটি সমবর্তী হতে পারে না"। এটি ইতিমধ্যে সম্মতি এবং সমান্তরালতার মধ্যে পার্থক্য বোঝার লড়াইয়ের মধ্য দিয়ে যাওয়ার পরে মনে রাখবেন ।

আমার নিজের গবেষণা করার পর, পরিশেষে আমি অনুপস্থিত টুকরা পাওয়া গেছে: select()। বিশেষ করে, আই মাল্টিপ্লেক্সিং, বিভিন্ন নাম অধীনে বিভিন্ন কার্নেলের দ্বারা বাস্তবায়িত: select(), poll(), epoll(), kqueue()। এগুলি এমন সিস্টেম কল যা বাস্তবায়নের বিশদগুলি পৃথক করার সাথে সাথে আপনাকে ফাইল বর্ণনাকারীদের একটি সেট দেখার জন্য অনুমতি দেয় । তারপরে আপনি অন্য একটি কল করতে পারেন যা অবরুদ্ধ হওয়া ফাইল বর্ণনাকারীর মধ্যে একটির পরিবর্তন না হওয়া পর্যন্ত অবরুদ্ধ করে।

সুতরাং, কেউ আইও ইভেন্টের একটি সেট (মূল ইভেন্ট লুপ) অপেক্ষা করতে পারে, প্রথম ইভেন্টটি সম্পন্ন করে এবং এটি ইভেন্ট লুপটিতে ফিরে আসে নিয়ন্ত্রণ পরিচালনা করতে পারে। পাখলান পুনরাবৃত্তি.

কিভাবে কাজ করে? ভাল, সংক্ষিপ্ত উত্তরটি হ'ল এটি কার্নেল এবং হার্ডওয়্যার-স্তরের যাদু। সিপিইউ ছাড়াও কম্পিউটারে অনেকগুলি উপাদান রয়েছে এবং এই উপাদানগুলি সমান্তরালভাবে কাজ করতে পারে। কার্নেল এই ডিভাইসগুলি নিয়ন্ত্রণ করতে পারে এবং নির্দিষ্ট সংকেত পাওয়ার জন্য তাদের সাথে সরাসরি যোগাযোগ করতে পারে।

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


25

awaitএবং টাস্ক না থ্যাডস asyncব্যবহার করুন ।

টাস্ক অবজেক্ট আকারে কিছু কাজ সম্পাদনের জন্য ফ্রেমওয়ার্কটিতে থ্রেডগুলির একটি পুল রয়েছে ; পুলটিতে একটি টাস্ক জমা দেওয়ার অর্থ টাস্ক অ্যাকশন পদ্ধতিতে কল করার জন্য একটি ইতিমধ্যে বিদ্যমান 1 , থ্রেড নির্বাচন করা।
একটি টাস্ক তৈরি করা একটি নতুন অবজেক্ট তৈরির বিষয়টি, নতুন থ্রেড তৈরির চেয়ে অনেক বেশি দ্রুত।

কোনও টাস্ক দেওয়া থাকলে এটির সাথে একটি ধারাবাহিকতা সংযুক্ত করা সম্ভব , থ্রেড শেষ হয়ে গেলে এটি কার্যকর করা একটি নতুন টাস্ক অবজেক্ট।

যেহেতু টাস্কasync/await ব্যবহার করে তারা নতুন থ্রেড তৈরি করে না ।


যদিও প্রতিটি আধুনিক ওএসে বিঘ্নিত প্রোগ্রামিং কৌশলটি ব্যাপকভাবে ব্যবহৃত হয়, তবে আমি মনে করি না যে তারা এখানে প্রাসঙ্গিক। একক সিপিইউ ব্যবহার করে
আপনার দুটি সমান্তরাল (প্রকৃতপক্ষে ইন্টারলিভড) কার্য সম্পাদন করতে পারে aysnc/await
ওএস সমর্থন করে আইওআরপি সমর্থন করে না এমনটি দিয়ে কেবল এটি ব্যাখ্যা করা যায় না ।


গতবার আমি সংকলকটি ডিএফএতে রূপান্তরিত asyncপদ্ধতিগুলি পরীক্ষা করেছিলাম , কাজটি ধাপে বিভক্ত হয়েছে, প্রত্যেকে একটি নির্দেশ দিয়ে শেষ করে । তার শুরু টাস্ক এবং পরবর্তী পদক্ষেপ চালানো ধারাবাহিকতায় সংযুক্ত করুন।await
await

একটি ধারণার উদাহরণ হিসাবে, এখানে একটি সিউডো-কোড উদাহরণ।
স্পষ্টতার স্বার্থে জিনিসগুলি সরল করা হচ্ছে এবং কারণ আমি সমস্ত বিবরণটি ঠিক মনে করি না।

method:
   instr1                  
   instr2
   await task1
   instr3
   instr4
   await task2
   instr5
   return value

এটি এমন কিছুতে রূপান্তরিত হয়

int state = 0;

Task nextStep()
{
  switch (state)
  {
     case 0:
        instr1;
        instr2;
        state = 1;

        task1.addContinuation(nextStep());
        task1.start();

        return task1;

     case 1:
        instr3;
        instr4;
        state = 2;

        task2.addContinuation(nextStep());
        task2.start();

        return task2;

     case 2:
        instr5;
        state = 0;

        task3 = new Task();
        task3.setResult(value);
        task3.setCompleted();

        return task3;
   }
}

method:
   nextStep();

1 প্রকৃতপক্ষে একটি পুলের কার্য তৈরির নীতি থাকতে পারে।


16

আমি এরিক লিপার্ট বা ল্যাসে ভি কার্লসেন এবং অন্যদের সাথে প্রতিযোগিতা করতে যাচ্ছি না, আমি কেবল এই প্রশ্নের অন্য একটি দিকের দিকে দৃষ্টি আকর্ষণ করতে চাই, যেটা আমার মনে হয় স্পষ্টভাবে উল্লেখ করা হয়নি।

awaitএটি নিজে ব্যবহার করা আপনার অ্যাপটিকে যাদুকরীভাবে প্রতিক্রিয়াশীল করে না। আপনি যে পদ্ধতিতে ইউআই থ্রেড ব্লকগুলি থেকে অপেক্ষায় রয়েছেন তা যদি না করেন তবে এটি এখনও আপনার ইউআইকে অপ্রত্যাশিত সংস্করণ হিসাবে অবরুদ্ধ করবে

আপনাকে আপনার প্রতীক্ষিত পদ্ধতিটি বিশেষত লিখতে হবে যাতে এটি হয় একটি নতুন থ্রেড ছড়িয়ে দেয় বা একটি সমাপ্তি বন্দরের মতো কিছু ব্যবহার করে (যা বর্তমান থ্রেডে কার্যকর হয় এবং যখনই সমাপ্তির বন্দরটি সিগন্যাল হয় তখন ধারাবাহিকতার জন্য অন্য কিছু কল করে)। তবে এই অংশটি অন্যান্য উত্তরে ভালভাবে ব্যাখ্যা করা হয়েছে।


3
এটি প্রথম স্থানে কোনও প্রতিযোগিতা নয়; এটি একটি সহযোগিতা!
এরিক লিপার্ট

16

এখানে আমি এই সমস্ত কীভাবে দেখছি এটি অতি প্রযুক্তিগতভাবে সঠিক নাও হতে পারে তবে এটি আমাকে সহায়তা করে অন্তত :)।

মেশিনে মূলত দুটি ধরণের প্রসেসিং (গণনা) হয়:

  • প্রসেসিং যা সিপিইউতে ঘটে
  • অন্যান্য প্রসেসরের (জিপিইউ, নেটওয়ার্ক কার্ড ইত্যাদি) প্রসেসিংয়ে, তাদের আইও বলি।

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

কিছু উদাহরণ:

  • যদি আমি FileStreamঅবজেক্টের লিখন পদ্ধতিটি ব্যবহার করি (যা একটি স্ট্রিম), প্রসেসিংয়ে বলা হবে, 1% সিপিইউ আবদ্ধ এবং 99% আইও আবদ্ধ।
  • যদি আমি NetworkStreamঅবজেক্টের লিখন পদ্ধতিটি ব্যবহার করি (যা একটি স্ট্রিম), প্রসেসিংয়ে বলা হবে, 1% সিপিইউ আবদ্ধ এবং 99% আইও আবদ্ধ।
  • যদি আমি Memorystreamঅবজেক্টের লিখন পদ্ধতিটি ব্যবহার করি (যা একটি স্ট্রিম), প্রসেসিং 100% সিপিইউ আবদ্ধ হবে।

সুতরাং, যেমন আপনি দেখতে পাচ্ছেন, কোনও অবজেক্ট-ভিত্তিক প্রোগ্রামার পয়েন্ট-অফ-ভিউ থেকে, যদিও আমি সর্বদা একটি অ্যাক্সেস অ্যাক্সেস করি তবে Streamনীচে যা ঘটে থাকে তা বস্তুর চূড়ান্ত প্রকারের উপর নির্ভর করে depend

এখন, জিনিসগুলি অনুকূল করতে, কখনও কখনও এটি সম্ভব এবং / অথবা প্রয়োজনীয় হলে সমান্তরালভাবে কোড চালাতে সক্ষম হয়ে উঠুন (নোট আমি অ্যাসিঙ্ক্রোনাস শব্দটি ব্যবহার করি না) দরকারী।

কিছু উদাহরণ:

  • একটি ডেস্কটপ অ্যাপ্লিকেশনটিতে, আমি একটি দস্তাবেজ মুদ্রণ করতে চাই, তবে আমি এটির জন্য অপেক্ষা করতে চাই না।
  • আমার ওয়েব সার্ভার একই সাথে অনেক ক্লায়েন্টকে সার্ভার করে, প্রত্যেকে তার পৃষ্ঠা সমান্তরালে পেয়ে থাকে (ক্রমিকায়িত হয় না)।

অ্যাসিঙ্ক / প্রতীক্ষার আগে, আমাদের মূলত এর দুটি সমাধান ছিল:

  • থ্রেডস । থ্রেড এবং থ্রেডপুল ক্লাস সহ এটি ব্যবহার করা তুলনামূলকভাবে সহজ ছিল। থ্রেডগুলি কেবল সিপিইউতে আবদ্ধ
  • "পুরানো" শুরু / শেষ / অ্যাসিঙ্কল্যাকব্যাক অ্যাসিনক্রোনাস প্রোগ্রামিং মডেল। এটি কেবলমাত্র একটি মডেল, আপনি সিপিইউ বা আইও আবদ্ধ হবেন কিনা তা আপনাকে জানায় না। আপনি যদি সকেট বা ফাইল স্ট্রিম ক্লাসগুলি একবার দেখুন, এটি আইও আবদ্ধ, যা দুর্দান্ত, তবে আমরা খুব কমই এটি ব্যবহার করি।

টাস্ক ধারণার উপর ভিত্তি করে async / প্রতীক্ষা কেবল একটি সাধারণ প্রোগ্রামিং মডেল । সিপিইউ বাউন্ড টাস্কের জন্য থ্রেড বা থ্রেড পুলের তুলনায় এটি ব্যবহার করা কিছুটা সহজ এবং পুরানো বিগ / এন্ড মডেলের চেয়ে ব্যবহার করা আরও সহজ। আন্ডারকভারস, তবে এটি উভয়ই একটি সুপার পরিশীলিত বৈশিষ্ট্য-পূর্ণ মোড়ক "" ঠিক "।

সুতরাং, আসল জয়টি বেশিরভাগই আইও বাউন্ড টাস্কগুলিতে হয় , সেই টাস্ক যা সিপিইউ ব্যবহার করে না, তবে অ্যাসিঙ্ক / অপেক্ষার কাজটি এখনও কেবল একটি প্রোগ্রামিং মডেল, এটি কীভাবে / কোথায় শেষ হবে প্রক্রিয়াটি নির্ধারণ করতে আপনাকে সহায়তা করে না।

এর অর্থ এটি নয় কারণ কোনও শ্রেণীর কাছে কোনও পদ্ধতি "ডোসোমিংথিংসিন্যাক" রয়েছে যে কোনও টাস্ক অবজেক্ট আপনি ফিরিয়ে আনতে পারবেন বলে ধরে নিতে পারেন এটি সিপিইউ আবদ্ধ হবে (যার অর্থ এটি সম্ভবত বেশ নিরর্থক , বিশেষত যদি এটির বাতিলকরণ টোকেন প্যারামিটার না থাকে), বা আইও বাউন্ড (যার অর্থ এটি সম্ভবত একটি আবশ্যক ), বা উভয়ের সংমিশ্রণ (যেহেতু মডেলটি বেশ ভাইরাল, বন্ধন এবং সম্ভাব্য সুবিধাগুলি শেষ পর্যন্ত হতে পারে, সুপার মিশ্রিত এবং এতটা স্পষ্ট নয়)।

সুতরাং, আমার উদাহরণগুলিতে ফিরে আসার পরে, মেমরিস্ট্রিম এ এসিএনসি / অপেক্ষার সাহায্যে আমার লিখন অপারেশনগুলি করা সিপিইউতে আবদ্ধ থাকবে (আমি সম্ভবত এটি থেকে উপকৃত হব না), যদিও আমি অবশ্যই ফাইল এবং নেটওয়ার্ক স্ট্রিমের সাথে এটি থেকে উপকৃত হব।


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

3

অন্যান্য উত্তরগুলির সংক্ষিপ্তসার:

অ্যাসিঙ্ক / অপেক্ষার বিষয়টি প্রাথমিকভাবে আইও বাউন্ড কাজের জন্য তৈরি করা হয় যেহেতু এগুলি ব্যবহার করে, কেউ কলিং থ্রেডকে ব্লক করা এড়াতে পারে। তাদের মূল ব্যবহারটি ইউআই থ্রেডগুলির সাথে হয় যেখানে আইও বাউন্ড অপারেশনে থ্রেডটি ব্লক করা পছন্দ হয় না।

অ্যাসিঙ্ক এটি নিজস্ব থ্রেড তৈরি করে না। কলিং পদ্ধতির থ্রেডটি অপেক্ষাকৃত সন্ধান না হওয়া পর্যন্ত অ্যাসিঙ্ক পদ্ধতিটি কার্যকর করতে ব্যবহৃত হয়। তারপরে একই থ্রেডটি async পদ্ধতি কলের বাইরে থাকা বাকি কলিং পদ্ধতিটি চালিয়ে যেতে থাকে। তথাকথিত থেকে ফিরে আসার পরে অ্যাসিঙ্ক পদ্ধতির মধ্যে, ধারাবাহিকতা থ্রেড পুল থেকে একটি থ্রেডে চালানো যেতে পারে - কেবলমাত্র পৃথক থ্রেড ছবিতে আসে।


ভাল সংক্ষিপ্তসার, তবে আমি মনে করি সম্পূর্ণ চিত্র দেওয়ার জন্য এটি আরও 2 টি প্রশ্নের উত্তর দেওয়া উচিত: ১. অপেক্ষার কোডটি কোন থ্রেডে কার্যকর করা হয়? ২) উল্লিখিত থ্রেড পুলটি কে বিকাশ / কনফিগার করে - বিকাশকারী বা রানটাইম পরিবেশ?
stodke

১. এই ক্ষেত্রে, বেশিরভাগ অপেক্ষিত কোডটি আইও বাউন্ড অপারেশন যা সিপিইউ থ্রেড ব্যবহার করবে না। যদি সিপিইউ বাউন্ড অপারেশনের জন্য অপেক্ষা করতে ইচ্ছুক হয় তবে একটি পৃথক টাস্ক তৈরি করা যেতে পারে। ২. থ্রেড পুলে থ্রেডটি টাস্ক শিডিয়ুলার দ্বারা পরিচালিত হয় যা টিপিএল কাঠামোর অংশ।
বৈভব কুমার

2

আমি নীচে এটি ব্যাখ্যা করার চেষ্টা করি। কেউ এটি সাহায্যকারী মনে হতে পারে। পাস্কালে ডস-এ সাধারণ গেমস তৈরি করার সময় আমি সেখানে ছিলাম, এটি করেছি, এটি পুনরায় নতুন করে নিয়েছি (ভাল পুরানো সময় ...)

সুতরাং ... প্রতিটি ইভেন্টে চালিত অ্যাপ্লিকেশনটির ভিতরে একটি ইভেন্ট লুপ থাকে যা এরকম কিছু:

while (getMessage(out message)) // pseudo-code
{
   dispatchMessage(message); // pseudo-code
}

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

ইভেন্ট হ্যান্ডলারের দ্রুত চালানো উচিত যাতে ইভেন্ট লুপটি আরও ইভেন্টের জন্য পোল করতে পারে এবং ইউআই সাড়া জাগায় remains যদি কোনও বোতাম ক্লিক এমন ব্যয়বহুল ক্রিয়াকলাপটি ট্রিগার করে তবে কী হবে?

void expensiveOperation()
{
    for (int i = 0; i < 1000; i++)
    {
        Thread.Sleep(10);
    }
}

ঠিক আছে নিয়ন্ত্রণটি কার্যকারিতাটির মধ্যে থেকে যাওয়ার সাথে সাথে 10 সেকেন্ড অপারেশন শেষ না হওয়া পর্যন্ত ইউআই প্রতিক্রিয়াশীল হয়ে ওঠে। এই সমস্যাটি সমাধান করার জন্য আপনাকে টাস্কটি ছোট ছোট অংশে বিভক্ত করতে হবে যা দ্রুত সম্পাদন করতে পারে। এর অর্থ আপনি একটি ইভেন্টে পুরো জিনিসটি পরিচালনা করতে পারবেন না। আপনাকে অবশ্যই কাজের একটি ছোট্ট অংশ করতে হবে, তারপরে ধারাবাহিকতার জন্য জিজ্ঞাসা করার জন্য ইভেন্টের কাতারে একটি অন্য ইভেন্ট পোস্ট করুন

সুতরাং আপনি এটিকে পরিবর্তন করবেন:

void expensiveOperation()
{
    doIteration(0);
}

void doIteration(int i)
{
    if (i >= 1000) return;
    Thread.Sleep(10); // Do a piece of work.
    postFunctionCallMessage(() => {doIteration(i + 1);}); // Pseudo code. 
}

এই ক্ষেত্রে কেবল প্রথম পুনরাবৃত্তি চলে তখন এটি পরবর্তী পুনরাবৃত্তিটি চালানোর জন্য ইভেন্টের কাতারে একটি বার্তা পোস্ট করে এবং প্রত্যাবর্তন করে। এটি আমাদের উদাহরণ postFunctionCallMessageসিউডো ফাংশন একটি "কল করুন এই ফাংশন" ইভেন্টটিকে কাতারে রাখে, তাই ইভেন্ট প্রেরণকারী যখন এটি পৌঁছে তখন এটি কল করবে। এটি দীর্ঘস্থায়ী কাজের টুকরো টুকরো টুকরো চালানোর সময় অন্যান্য সমস্ত জিইউআই ইভেন্টগুলি প্রক্রিয়া করার অনুমতি দেয়।

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

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

তবে ম্যানুয়ালি এই সমস্ত চেইনকে ছোট ছোট টুকরো টুকরো টুকরো করে ভাগ করা একটি জটিল কাজ এবং সম্পূর্ণরূপে যুক্তির বিন্যাসকে .ContinueWithমেসেজ করে, কারণ পুরো ব্যাকগ্রাউন্ড টাস্ক কোডটি মূলত একটি গোলযোগ। সংকলক আপনাকে এখানে সহায়তা করে। এটি ব্যাকগ্রাউন্ডে আপনার জন্য এই সমস্ত শৃঙ্খলা এবং ধারাবাহিকতা করে। আপনি যখন বলছেন awaitআপনি সংকলককে বলুন যে "এখানে থামুন, বাকি ফাংশনটি একটি ধারাবাহিকতা টাস্ক হিসাবে যুক্ত করুন"। সংকলক বিশ্রামের যত্ন নেয়, যাতে আপনার প্রয়োজন হয় না।


0

আসলে, async awaitচেইনগুলি সিএলআর সংকলক দ্বারা উত্পাদিত রাষ্ট্র মেশিন।

async await তবে টিপিএল থ্রেড পুল ব্যবহার করছে এমন থ্রেডগুলি কার্য সম্পাদন করতে ব্যবহার করে।

অ্যাপ্লিকেশনটিকে অবরুদ্ধ না করার কারণটি হ'ল রাষ্ট্রের মেশিনটি সিদ্ধান্ত নিতে পারে কোনটি সহ-রুটিন কার্যকর করা, পুনরাবৃত্তি করা, চেক করা এবং আবার সিদ্ধান্ত নেওয়া উচিত।

আরও পড়া:

অ্যাসিঙ্ক এবং উত্পন্ন করার জন্য কী অপেক্ষা করছে?

অ্যাসিঙ্ক অ্যাওয়েট এবং জেনারেটেড স্টেটম্যাচাইন

অ্যাসিঙ্ক্রোনাস সি # এবং এফ # (III): এটি কীভাবে কাজ করে? - টমাস পেট্রিসেক

সম্পাদনা করুন :

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


0

এটি সরাসরি প্রশ্নের উত্তর দিচ্ছে না, তবে আমি মনে করি এটি একটি আন্তঃব্যক্তিক সংযোজনীয় তথ্য:

অ্যাসিঙ্ক এবং প্রতীক্ষা নিজেই নতুন থ্রেড তৈরি করে না। তবে আপনি যেখানে async অপেক্ষা করছেন তার উপর নির্ভর করে, অপেক্ষার আগে সিনক্রোনাস অংশটি সিনক্রোয়াস অংশের চেয়ে আলাদা থ্রেডে চলতে পারে (যেমন ASP.NET এবং ASP.NET কোর আলাদা আচরণ করে)।

ইউআই-থ্রেড ভিত্তিক অ্যাপ্লিকেশনগুলিতে (উইনফোর্ডস, ডাব্লুপিএফ) আপনি আগে এবং পরে একই থ্রেডে থাকবেন। তবে আপনি যখন থ্রেড পুলের থ্রেডে অ্যাসিঙ্কটি দূরে ব্যবহার করেন, অপেক্ষার আগে এবং পরে থ্রেডটি একই রকম নাও হতে পারে।

এই বিষয় একটি দুর্দান্ত ভিডিও

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