কেন কেউ সি # তে ভ্যালুটাস্ক <T> ওভার টাস্ক <T> ব্যবহার করবে?


168

সি # 7.0 হিসাবে অ্যাসিঙ্ক পদ্ধতিতে ভ্যালু টাস্ক <T> ফিরে আসতে পারে। ব্যাখ্যায় বলা হয়েছে যে যখন আমাদের কোনও ক্যাশেড ফলাফল হয় বা সিঙ্ক্রোনাস কোডের মাধ্যমে অ্যাসিঙ্ক সিমুলেট করা হয় তখন এটি ব্যবহার করা উচিত। তবে আমি এখনও বুঝতে পারি না যে সবসময় ভ্যালুটাস্ক ব্যবহার করতে সমস্যা হয় বা আসলে কেন শুরু থেকে কোনও মূল্য টাইপের সাথে অ্যাসিঙ্ক / প্রতীক্ষা করা হয়নি। কখন ভ্যালুটাস্ক কাজটি করতে ব্যর্থ হবে?


7
আমি সন্দেহ করি যে এটি ValueTask<T>(বরাদ্দের শর্তে) আসলে অপরিহার্য ক্রিয়াকলাপগুলির জন্য বাস্তবায়ন না করার সুবিধার সাথে করণীয় (কারণ সেক্ষেত্রে ValueTask<T>এখনও স্তূপ বরাদ্দ প্রয়োজন হবে)। Task<T>গ্রন্থাগারগুলির মধ্যে অন্যান্য প্রচুর সমর্থন থাকার বিষয়টিও রয়েছে ।
জন স্কিটি 13

3
@ জোনস্কিট বিদ্যমান লাইব্রেরিগুলি একটি সমস্যা তবে এই প্রশ্নটি শুরু করে যে টাস্কটি শুরু থেকেই ভ্যালুটাস্ক হওয়া উচিত ছিল? আসল অ্যাসিঙ্ক স্টাফের জন্য এটি ব্যবহার করার সময় সুবিধার অস্তিত্ব থাকতে পারে তবে এটি কি ক্ষতিকারক?
স্টিলগার

8
আমি জানাতে পারব এমন বেশি জ্ঞানের জন্য github.com/dotnet/corefx/issues/4708#issuecomment-160658188 দেখুন :)
জন স্কিটি


3
@ জোয়েলমিউলারের প্লটটি আরও ঘন হয় :)
স্টিলগার

উত্তর:


245

থেকে এপিআই ডক্স (জোর দেওয়া যোগ):

পদ্ধতিগুলি এই মান প্রকারের একটি উদাহরণ ফিরে আসতে পারে যখন সম্ভবত তাদের ক্রিয়াকলাপগুলির ফলাফল সিঙ্ক্রোনিকভাবে উপলব্ধ হবে এবং যখন পদ্ধতিটি এত ঘনিয়ে আসার প্রত্যাশা করা হয় তবে নতুন বরাদ্দকরণের ব্যয় হয়Task<TResult> প্রতিটি কলের জন্য নিষিদ্ধ হবে।

সেখানে ব্যবহার করে একটি থেকে tradeoffs হয় ValueTask<TResult>একটি পরিবর্তে Task<TResult>। উদাহরণস্বরূপ, যখন ValueTask<TResult>সফল ফলাফলটি সিঙ্ক্রোনিকভাবে পাওয়া যায় সেই ক্ষেত্রে একটি বরাদ্দ এড়াতে সাহায্য করতে পারে, তবে এটিতে দুটি ক্ষেত্র রয়েছে যখন Task<TResult>রেফারেন্স টাইপ হিসাবে একটি ক্ষেত্র। এর অর্থ হ'ল কোনও মেথড কল একটির পরিবর্তে দুটি ক্ষেত্রের মূল্য ফিরিয়ে দেয়, যা অনুলিপি করার জন্য আরও বেশি ডেটা। এর অর্থ এটিও হ'ল যে কোনও পদ্ধতির মধ্যে যদি এইগুলির মধ্যে একটি ফেরত দেয় কোনও পদ্ধতির জন্য অপেক্ষা করা হয় asyncতবে সেই asyncপদ্ধতির রাষ্ট্রীয় মেশিনটি একক রেফারেন্সের পরিবর্তে দুটি ক্ষেত্রের স্ট্রাক্ট সংরক্ষণ করার প্রয়োজনের কারণে আরও বড় হবে।

তদ্ব্যতীত, অ্যাসিক্রোনাস অপারেশনের ফলে গ্রাহ্য হওয়ার পরিবর্তে অন্যান্য ব্যবহারগুলির জন্য await, ValueTask<TResult>আরও সংশ্লেষিত প্রোগ্রামিং মডেল হতে পারে, যার ফলস্বরূপ আরও বেশি বরাদ্দ হতে পারে। উদাহরণস্বরূপ, এমন একটি পদ্ধতি বিবেচনা করুন Task<TResult>যা কোনও ক্যাশেড টাস্কের সাথে সাধারণ ফলাফল হিসাবে ফিরে আসতে পারে বা এ ValueTask<TResult>। ফলাফল ভোক্তা এটি একটি হিসাবে ব্যবহার করতে চায় Task<TResult>মত পদ্ধতি সঙ্গে যেমন ব্যবহার হিসেবে Task.WhenAllএবং Task.WhenAny, ValueTask<TResult>প্রথমে একটি রূপান্তরিত করা করতে হবে Task<TResult>ব্যবহার AsTask, যা একটি বরাদ্দ যে যদি একটি ক্যাশে হবে এড়ানো হয়েছে বিশালাকার Task<TResult>ব্যবহার করা হয়েছে প্রথম অবস্থানে.

এই হিসাবে, যে কোনও অ্যাসিনক্রোনাস পদ্ধতির জন্য ডিফল্ট পছন্দটি একটি Taskবা ফিরে আসা উচিত Task<TResult>। পারফরম্যান্স বিশ্লেষণ যদি এটিকে সার্থক প্রমাণ করে তবে ValueTask<TResult>তার পরিবর্তে এটি ব্যবহার করা উচিত Task<TResult>


7
@ ম্যাট থমাস: এটি একটি একক Taskবরাদ্দ সংরক্ষণ করে (যা এই দিনগুলিতে ছোট এবং সস্তা) তবে কলারের বিদ্যমান বরাদ্দকে আরও বড় করা এবং ফেরতের মূল্যের আকার দ্বিগুণ করার ব্যয়ে (নিবন্ধকের বরাদ্দকে প্রভাবিত করে)। যদিও এটি কোনও বাফার পঠিত দৃশ্যের জন্য পরিষ্কার পছন্দ, এটিকে সমস্ত ইন্টারফেসে ডিফল্টরূপে প্রয়োগ করা আমার প্রস্তাবিত জিনিস নয়।
স্টিফেন ক্লিয়ারি

1
ডান, হয় Taskবা ValueTaskএকটি সিঙ্ক্রোনাস রিটার্ন টাইপ হিসাবে (হিসাবে Task.FromResult) হিসাবে ব্যবহার করা যেতে পারে । তবে ValueTaskআপনার কাছে সিঙ্ক্রোনাস হওয়ার কিছু প্রত্যাশা থাকলেও এর মান (হি) রয়েছে । ReadByteAsyncএকটি সর্বোত্তম উদাহরণ হচ্ছে। আমি বিশ্বাস করি ValueTask মূলত নতুন "চ্যানেল" (নিম্ন-স্তরের বাইট স্ট্রিম) এর জন্য তৈরি করা হয়েছিল, সম্ভবত এটিএসপি.এনইটি কোরতেও ব্যবহৃত হয় যেখানে কার্য সম্পাদন সত্যই গুরুত্বপূর্ণ।
স্টিফেন ক্লিয়ারি

1
ওহ আমি জানি যে লোল, আপনার যদি সেই নির্দিষ্ট মন্তব্যে কিছু যোগ করার থাকে তবে কেবল ভাবছিলাম;)
জুলাইগলন

2
না এই জনসংযোগ ValueTask করা উচিত ছিল হাতে ভারসাম্য স্যুইচ করবেন? (রেফ: blog.marcgravell.com/2019/08/… )

2
@ স্টুয়ার্ট: আপাতত, আমি এখনও Task<T>ডিফল্ট হিসাবে ব্যবহারের পরামর্শ দেব । এটি কেবল কারণ বেশিরভাগ বিকাশকারীরা চারপাশের বিধিনিষেধগুলির সাথে পরিচিত নন ValueTask<T>(বিশেষত, "শুধুমাত্র একবার ব্যবহার করুন" নিয়ম এবং "কোনও অবরুদ্ধকরণ নয়" নিয়ম)। এটি বলেছিল, যদি আপনার দলের সমস্ত ডেভসগুলি ভাল থাকে ValueTask<T>তবে আমি পছন্দ করার জন্য একটি টিম-স্তরের গাইডলাইনটি সুপারিশ করব ValueTask<T>
স্টিফেন ক্লিয়ারি

104

তবে আমি এখনও বুঝতে পারি না যে সবসময় ভ্যালু টাস্ক ব্যবহার করতে সমস্যা

কাঠামোর ধরণগুলি নিখরচায় নয়। কোনও রেফারেন্সের আকারের চেয়ে বড় স্ট্রাইকগুলি অনুলিপি করা কোনও রেফারেন্স অনুলিপি করার চেয়ে ধীর হতে পারে। রেফারেন্সের চেয়ে বড় স্ট্রাক্ট স্ট্রোক রেফারেন্স সংরক্ষণের চেয়ে বেশি মেমরি লাগে takes B৪ বিটের চেয়ে বড় স্ট্রাক্টগুলি রেফারেন্স নিবন্ধন করা যেতে পারে যখন নিবন্ধভুক্ত নাও হতে পারে। নিম্ন সংগ্রহের চাপের সুবিধাগুলি ব্যয় ছাড়িয়ে যাবে না।

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

কেন async / প্রতীক্ষা শুরু থেকে কোনও মান ধরণের দিয়ে নির্মিত হয়নি।

awaitTask<T>টাইপ ইতিমধ্যে বিদ্যমান থাকার পরে সি # তে যুক্ত করা হয়েছিল । এটি ইতিমধ্যে বিদ্যমান থাকলে কোনও নতুন প্রকার আবিষ্কার করতে কিছুটা বিভ্রান্ত হত। আর awaitএক যে 2012 সালে জাহাজে ছিল নিখুঁত ভাল শত্রু উপর প্রতিষ্ঠাপন আগে বহুসংখ্যক নকশা পুনরাবৃত্তিও মাধ্যমে গিয়েছিলাম; বিদ্যমান অবকাঠামোর সাথে ভালভাবে কাজ করে এমন একটি সমাধান পাঠাতে আরও ভাল এবং তারপরে যদি ব্যবহারকারীদের চাহিদা থাকে তবে পরে উন্নতি সরবরাহ করুন।

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

কেউ কি ভ্যালুটাস্ক কাজটি করতে ব্যর্থ হবে তা ব্যাখ্যা করতে পারে?

জিনিসটির উদ্দেশ্যটি উন্নত কর্মক্ষমতা। এটি কাজ করে না যদি এটি পরিমাপযোগ্যভাবে এবং উল্লেখযোগ্যভাবে পারফরম্যান্সের উন্নতি না করে। এটি যে কোনও গ্যারান্টি নেই।


23

ValueTask<T>Task<T>এটি একটি সুপারসেটের উপসেট নয়

ValueTask<T>এটি একটি টি এবং এ এর ​​একটি বৈষম্যমূলক ইউনিয়ন, এটি উপলব্ধ একটি টি মান সমকালীনভাবে ফেরত দেওয়ার Task<T>জন্য এটি বরাদ্দ-মুক্ত করে তোলে ReadAsync<T>(ব্যবহারের বিপরীতে Task.FromResult<T>, যা একটি Task<T>উদাহরণ বরাদ্দ করা প্রয়োজন )। ValueTask<T>প্রতিক্ষণযোগ্য, তাই বেশিরভাগ দৃষ্টান্তগুলির ব্যবহার একটি এর সাথে আলাদা করা যায় না Task<T>

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

সুতরাং এটি আপনাকে এমন একটি পদ্ধতি লিখতে দেয় যা হয় অ্যাসিনক্রোনাস বা সিঙ্ক্রোনাস হয়, বরং প্রতিটিটির জন্য একটি অন্যভাবে অভিন্ন পদ্ধতি লিখতে দেয়। আপনি যে কোনও জায়গায় এটি ব্যবহার করতে পারেন Task<T>তবে এটি প্রায়শই কিছু যুক্ত করে না।

ঠিক আছে, এটি একটি জিনিস যুক্ত করে: এটি কলারের কাছে একটি অন্তর্ভুক্ত প্রতিশ্রুতি যুক্ত করে যে পদ্ধতিটি ValueTask<T>সরবরাহ করে যে অতিরিক্ত কার্যকারিতা সরবরাহ করে। আমি ব্যক্তিগতভাবে প্যারামিটার এবং রিটার্নের ধরণের পছন্দ পছন্দ করি যা কলকারীকে যতটা সম্ভব বলে দেয়। IList<T>যদি গণনা একটি গণনা প্রদান করতে না পারে তবে ফিরে আসবেন না; ফেরত না IEnumerable<T>যদি এটা করতে পারেন। আপনার কোন পদ্ধতিটি যুক্তিসঙ্গতভাবে সিঙ্ক্রোনালি বলা যেতে পারে এবং কোনটি পারে না তা জানতে আপনার গ্রাহকদের কোনও ডকুমেন্টেশন সন্ধান করতে হবে না।

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

শক্তিশালী টাইপিংয়ের জন্য এটি মূলত।

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

পদ্ধতিটি লেখার লোকটি যদি এটি না জানত যে এটিকে সমকালীনভাবে বলা যেতে পারে, পৃথিবীতে কে করে ?!

আপনার যদি এমন অনেক অনভিজ্ঞ প্রোগ্রামার থাকে যা এসিঙ্ক পদ্ধতিগুলি লেখেন তবে সেই একই লোকেরা কি তাদেরও ডাকছে? তারা কী এ্যাসিঙ্ক কল করা নিরাপদ তাদের নিজেরাই নির্ধারণের জন্য যোগ্য, বা তারা কীভাবে এই বিষয়গুলিকে কল করে তার অনুরূপ নিয়ম প্রয়োগ শুরু করবে?

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


4
যদি আমি কোনও পদ্ধতি ফিরতে দেখি তবে ValueTask<T>আমি ধরে নিই যে যে পদ্ধতিটি লিখেছিল সে লোকটি করেছে কারণ পদ্ধতিটি আসলে কার্যকারিতাটি ব্যবহার করেValueTask<T> যোগ যুক্ত করে। আপনার সমস্ত পদ্ধতির জন্য একই রকম ফেরতের ধরণ কেন আপনি পছন্দ করেন বলে আমি বুঝতে পারি না। সেখানে লক্ষ্য কি?
15ee8f99-57ff-4f92-890c-b56153

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

6
আমার দৃষ্টিতে, এটি প্রায় আপনার সমস্ত পদ্ধতি ফিরে আসার মতো objectকারণ সম্ভবত কোনও দিন আপনি তাদের intপরিবর্তে ফিরে আসতে চাইবেন string
15ee8f99-57ff-4f92-890c-b56153

3
হতে পারে তবে যদি আপনি "আপনি কেন বস্তুর পরিবর্তে কোনও স্ট্রিং ফিরে আসবেন" প্রশ্নটি জিজ্ঞাসা করলে আমি সহজেই টাইপ সুরক্ষার অভাবের দিকে ইঙ্গিত করে এর উত্তর দিতে পারি। ValueTask সর্বত্র ব্যবহার না করার কারণগুলি আরও সূক্ষ্ম বলে মনে হয়।
স্টিলগার

3
@ স্টিলগার একটি জিনিস আমি বলব: সূক্ষ্ম সমস্যাগুলি আপনাকে সুস্পষ্ট সমস্যাগুলির চেয়ে বেশি উদ্বিগ্ন হওয়া উচিত।
15ee8f99-57ff-4f92-890c-b56153

20

নেট কোর ২.১ এ কিছু পরিবর্তন রয়েছে । .NET কোর 2.1 থেকে শুরু করে ভ্যালুটাস্ক কেবল সিঙ্ক্রোনাস সম্পন্ন ক্রিয়াকলাপগুলিকেই নয় তবে অ্যাসিঙ্কটিও সম্পন্ন করে। এছাড়াও আমরা অ-জেনেরিক ValueTaskপ্রকারটি পাই ।

আমি আপনার প্রশ্নের সাথে সম্পর্কিত যা স্টিফেন টুব মন্তব্যটি ছেড়ে দেব :

আমাদের এখনও গাইডলাইন আনুষ্ঠানিক করা দরকার, তবে আমি আশা করি এটি সর্বজনীন এপিআই পৃষ্ঠের ক্ষেত্রের জন্য এমন কিছু হবে:

  • কার্য সর্বাধিক ব্যবহারযোগ্যতা সরবরাহ করে।

  • পারফরম্যান্স অপটিমাইজেশনের জন্য ভ্যালু টাস্ক সর্বাধিক বিকল্প সরবরাহ করে।

  • যদি আপনি এমন একটি ইন্টারফেস / ভার্চুয়াল পদ্ধতি লিখছেন যা অন্যরা ওভাররাইড করে, মান মান ডিফল্ট পছন্দ।

  • যদি আপনি আশা করেন যে এপিআইটি হট পাথগুলিতে ব্যবহার করা হবে যেখানে বরাদ্দগুলি বিবেচিত হবে, তবে ভ্যালু টাস্ক একটি ভাল পছন্দ।

  • অন্যথায়, যেখানে কর্মক্ষমতা গুরুতর নয়, কার্যের ক্ষেত্রে ডিফল্ট, এটি আরও ভাল গ্যারান্টি এবং ব্যবহারযোগ্যতা সরবরাহ করে।

বাস্তবায়নের দৃষ্টিকোণ থেকে, ফিরে আসা বেশিরভাগ ভ্যালুটাস্কের উদাহরণগুলি এখনও টাস্কের দ্বারা সমর্থিত হবে।

বৈশিষ্ট্যটি কেবল নেট নেট 2.1 এ ব্যবহার করা যায় না। আপনি এটি System.Threading.Tasks.Extensions প্যাকেজের সাহায্যে ব্যবহার করতে সক্ষম হবেন ।


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