অকার্যকর ফিরে আসা এবং একটি টাস্ক ফিরিয়ে দেওয়ার মধ্যে পার্থক্য কী?


128

বিভিন্ন সি # অ্যাসিঙ্ক সিটিপি নমুনাগুলি দেখে আমি কিছু অ্যাসিঙ্ক ফাংশন দেখতে পাই যা আবার ফিরে আসে voidএবং অন্যরা জেনারিককে ফিরিয়ে দেয় Task। আমি দেখতে পাচ্ছি যে Task<MyType>এসিএনসি অপারেশন শেষ হওয়ার সাথে সাথে কলটি ডেটা ফিরিয়ে দেওয়া কেন দরকারী, তবে যে ফাংশনগুলিতে আমি দেখেছি যে রিটার্ন টাইপ রয়েছে তা Taskকখনই কোনও ডেটা ফেরত দেয় না। ফিরবে না কেন void?

উত্তর:


214

স্লাকস এবং কিলারক্যামের উত্তরগুলি ভাল; আমি ভেবেছিলাম আমি আরও কিছু প্রসঙ্গ যুক্ত করব।

আপনার প্রথম প্রশ্নটি কী কী পদ্ধতিতে চিহ্নিত করা যায় সে সম্পর্কে মূলত async

একটি পদ্ধতি হিসেবে চিহ্নিত asyncআসতে পারেন void, Taskঅথবা Task<T>। তাদের মধ্যে পার্থক্য কি কি?

একটি Task<T>ফেরার ASYNC পদ্ধতি প্রতীক্ষিত হতে পারে, এবং যখন টাস্ক সমাপ্ত এটি একটি টি আপ দিতে চাওয়া হবে

একটি Taskরিটার্নিং অ্যাসিঙ্ক পদ্ধতিটি অপেক্ষা করা যেতে পারে এবং যখন টাস্কটি সম্পূর্ণ হয়, কাজটির ধারাবাহিকতাটি চালানোর জন্য নির্ধারিত হয়।

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

আপনার দ্বিতীয় প্রশ্ন, একটি মন্তব্যে মূলত কী সম্পাদনা করা যেতে পারে তা সম্পর্কে await:

কি ধরণের পদ্ধতি awaitএড করা যেতে পারে ? একটি শূন্য-ফিরে পদ্ধতি কি awaitএডিট করা যেতে পারে ?

না, একটি অকার্যকর-প্রত্যাবর্তন পদ্ধতি অপেক্ষা করা যায় না। সংকলক await M()একটি কলটিতে অনুবাদ করে M().GetAwaiter(), যেখানে GetAwaiterকোনও উদাহরণ পদ্ধতি বা কোনও এক্সটেনশন পদ্ধতি হতে পারে। প্রতীক্ষিত মানটি এমন একটি হতে হবে যার জন্য আপনি একটি দর্শনার্থী পেতে পারেন; স্পষ্টত একটি শূন্য-ফেরত পদ্ধতি একটি মান উত্পাদন করে না যা থেকে আপনি একটি দর্শনার্থী পেতে পারেন।

Taskপুনরুদ্ধার পদ্ধতি অপেক্ষাকৃত মান তৈরি করতে পারে। আমরা প্রত্যাশা করি যে তৃতীয় পক্ষগুলি তাদের পছন্দ Taskমতো বস্তুর নিজস্ব বাস্তবায়ন তৈরি করতে চাইবে যা আপনি অপেক্ষা করতে পারবেন এবং আপনি তাদের জন্য অপেক্ষা করতে সক্ষম হবেন। যাইহোক, আপনাকে asyncএমন পদ্ধতিগুলি ঘোষণার অনুমতি দেওয়া হবে না যা কেবল বা void, ছাড়া কিছু ফেরত দেয় ।TaskTask<T>

(আপডেট): আমার শেষ বাক্যটি সি # এর ভবিষ্যতের সংস্করণ দ্বারা মিথ্যা বলা যেতে পারে; অ্যাসিঙ্ক পদ্ধতির জন্য টাস্ক টাইপ ব্যতীত অন্যান্য রিটার্নের ধরণের অনুমতি দেওয়ার প্রস্তাব রয়েছে।)

(আপডেট: উপরে উল্লিখিত বৈশিষ্ট্যটি এটি সি # 7. এ তৈরি করেছে)


7
+1 আমি মনে করি যে একমাত্র জিনিস অনুপস্থিত তা হ'ল শূন্য-প্রত্যাবর্তনকারী অ্যাসিঙ্ক পদ্ধতিতে ব্যতিক্রমগুলি কীভাবে আচরণ করা হয়।
জোও অ্যাঞ্জেলো

10
@ জামেসক্যাড: ধরুন কিছু অ্যাসিক্রোনাস কাজ ব্যতিক্রম ছুঁড়ে ফেলেছে। কে এটা ধরে? অ্যাসিক্রোনাস টাস্ক শুরু করা কোডটি এখন আর স্ট্যাকের মধ্যে নেই - এটি একই থ্রেডেও নাও থাকতে পারে - এবং ব্যতিক্রমগুলি ধরে নিয়েছে যে সমস্ত ক্যাচ / অবশেষে ব্লকগুলি স্ট্যাকের মধ্যে রয়েছে । তো তুমি কি কর? আমরা ব্যতিক্রমের তথ্যটি টাস্কে সঞ্চয় করি, যাতে আপনি এটি পরে পরীক্ষা করতে পারেন। তবে যদি পদ্ধতিটি বাতিল হয়ে যায় তবে ব্যবহারকারীর কোডে কোনও টাস্ক নেই। আমরা কীভাবে সেই পরিস্থিতিটি মোকাবিলা করেছি তা কিছুটা বিতর্কের বিষয় হয়ে দাঁড়িয়েছে এবং আমরা কী সিদ্ধান্ত নিয়েছি তা এই মুহুর্তে মনে নেই।
এরিক লিপার্ট

8
আমি আসলে বিল্ডে স্টিফেন টুবের এই প্রশ্নটি জিজ্ঞাসা করেছি। .NET 4.0 অনাবদ্ধ, টাস্কগুলিতে হাতছাড়া হওয়া ব্যতিক্রমগুলি শেষ পর্যন্ত প্রক্রিয়াটি ক্র্যাশ করবে যখন টিপিএল সনাক্ত করে যে সেগুলি পর্যবেক্ষণ করা হয়নি। ৪.৪ এ তারা ডিফল্ট আচরণটি পরিবর্তন করেছে যাতে অনাবৃত ব্যতিক্রমগুলি এখনও টাস্কশেডুলার :: আনবস্ক্রিয়ড টাস্কএক্সসেপশন ইভেন্টের মাধ্যমে জানানো হবে, তবে প্রক্রিয়া আর ক্রাশ হবে না। আপনি যদি পুরানো behavior.০ আচরণটি চান তবে আপনি <রুনটাইম> <থ্রোঅনোব্রিজড টাস্কএক্সেপশন সক্ষম হওয়া = "সত্য" /> </ রুনটাইম> এর সাথে ফিরে যেতে পারেন। সম্ভবত পরিবর্তন অকার্যকর অ্যাসিঙ্ক পদ্ধতির জন্য অগ্নি-বিস্মরণকে সমর্থন করার জন্য যথাযথভাবে করা হয়েছিল।
ড্র মার্শ

4
async voidপদ্ধতিগুলি SynchronizationContextকার্যকর করতে শুরু করার সময় সক্রিয় ছিল সেটির ক্ষেত্রে তাদের ব্যতিক্রম বাড়ে । এটি (সিঙ্ক্রোনাস) ইভেন্ট হ্যান্ডলারের আচরণের মতো। @ ড্র্রুমার্শ: UnobservedTaskExceptionএবং রানটাইম সেটিংটি কেবল "ফায়ার অ্যান্ড ভুলে" async টাস্ক পদ্ধতিগুলিতে প্রয়োগ হয়, async voidপদ্ধতি নয় ।
স্টিফেন ক্লিয়ারি


23

যদি ফোনকারী কাজটির জন্য অপেক্ষা করতে চান বা ধারাবাহিকতা যুক্ত করতে চান।

আসলে, ফিরে আসার একমাত্র কারণ আপনি voidযদি ফিরে না আসতে পারেন তবে আপনি Taskইভেন্ট হ্যান্ডলারটি লিখছেন।


আমি ভেবেছিলাম এমন পদ্ধতিগুলির জন্য অপেক্ষা করাও সম্ভব যেগুলি একটি শূন্য প্রকারটিও ফেরত দেয় - আপনি কি কিছুটা ব্যাখ্যা করতে পারবেন?
জেমস ক্যাড

1
না, আপনি পারবেন না। যদি পদ্ধতিটি ফিরে আসে void, আপনার যে কাজটি উত্পন্ন করে তা পাওয়ার কোনও উপায় নেই। (আসলে, এটি এমনকি আদৌ উত্পন্ন করে কিনা তা আমি নিশ্চিত নই Task)
স্লাকস

18

পদ্ধতিগুলি ফিরে আসার Taskএবং Task<T>কম্পোজেবল - এর অর্থ আপনি awaitকোনও asyncপদ্ধতির অভ্যন্তরে এগুলি করতে পারেন ।

asyncফিরতি পদ্ধতিগুলি voidকমপোজ্য নয়, তবে তাদের আরও দুটি গুরুত্বপূর্ণ বৈশিষ্ট্য রয়েছে:

  1. এগুলি ইভেন্ট হ্যান্ডলার হিসাবে ব্যবহার করা যেতে পারে।
  2. তারা একটি "শীর্ষ-স্তরের" অ্যাসিনক্রোনাস অপারেশন উপস্থাপন করে।

দ্বিতীয় বিষয়টি গুরুত্বপূর্ণ যখন আপনি একটি প্রসঙ্গের সাথে কাজ করছেন যা অসামান্য ক্রমবর্ধমান অপারেশনগুলির একটি গণনা বজায় রাখে ।

এএসপি.এনইটি প্রসঙ্গটি এমন একটি প্রসঙ্গ; যদি আপনি Taskকোনও অ্যাসিঙ্ক voidপদ্ধতি থেকে অপেক্ষার ছাড়াই অ্যাসিঙ্ক পদ্ধতিগুলি ব্যবহার করেন তবে এএসপি.এনইটি অনুরোধটি খুব তাড়াতাড়ি সম্পন্ন হবে।

আরেকটি প্রসঙ্গ হ'ল AsyncContextআমি ইউনিট পরীক্ষার জন্য এখানে লিখেছি ( এখানে উপলভ্য ) - AsyncContext.Runপদ্ধতিটি অসামান্য অপারেশন গণনা ট্র্যাক করে এবং শূন্য হলে ফিরে আসে।


12

প্রকার Task<T>কাজের workhorse টাইপ সমান্তরাল লাইব্রেরি (TPL), এটি "কিছু কাজ / চাকরি যে ধরনের কোনো ফলাফল যাচ্ছে ধারণা প্রতিনিধিত্ব করে Tভবিষ্যতে"। "এমন কাজ যা ভবিষ্যতে সম্পূর্ণ হবে তবে কোনও ফল দেয় না" ধারণাটি অ-জেনেরিক টাস্ক ধরণের দ্বারা প্রতিনিধিত্ব করা হয়।

ঠিক কীভাবে ফলাফলের ফলাফল Tতৈরি হতে চলেছে এবং কোনও নির্দিষ্ট কাজের বাস্তবায়ন বিশদ; কাজটি স্থানীয় মেশিনে অন্য কোনও থ্রেডে, অন্য থ্রেডে আনা যেতে পারে T টিপিএল কার্য সাধারণত বর্তমান প্রক্রিয়ায় একটি থ্রেড পুল থেকে শ্রমিকের থ্রেডগুলিতে রচনা করা হয়, তবে বাস্তবায়নের বিশদটি এই Task<T>ধরণের মৌলিক নয় ; বরং একটি Task<T>যে কোনও উচ্চ-বিলম্বিত অপারেশনকে উপস্থাপন করতে পারে যা একটি T

উপরে আপনার মন্তব্যের ভিত্তিতে:

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


সম্পাদনা: আমার ২০১ric সালের অক্টোবরে এরিক লিপার্টের নিবন্ধটি উদ্ধৃত করা উচিত এমএসডিএন ম্যাগাজিন কারণ এটি এই জিনিসটি প্রথম স্থানে বোঝার ক্ষেত্রে আমার পক্ষে এক বড় সহায়ক ছিল।

লোডগুলির জন্য আরও ইনফ্রোমেশন এবং হোয়াইটপেজগুলি এখানে দেখুন

আমি এই কিছু সাহায্য আশা করি।

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