কীওয়ার্ড না থাকা সম্পর্কে কীভাবে?
আমি সংকলকটি বুঝতে পারি যে বেশিরভাগ সময় আমি যখন অ্যাসিক্রোনাস পদ্ধতিতে কল করি তখন আমি এর ফলাফল চাই want
Document doc = DownloadDocumentAsync();
এটাই. এই জিনিসটির জন্য কীওয়ার্ডটি ভাবার জন্য লোকেরা যেভাবে কঠিন সময় কাটাচ্ছে তা হ'ল কারণ "জিনিসগুলি পুরোপুরি স্বাভাবিক থাকলে আপনি যে কাজটি করতেন তা কর" এর মতো একটি কীওয়ার্ড থাকার মতো। এটি ডিফল্ট হওয়া উচিত, কোনও কীওয়ার্ডের প্রয়োজন নেই।
হালনাগাদ
আমি মূলত পরামর্শ দিয়েছিলাম যে কম্পাইলারটি কী করণীয় তা নির্ধারণের জন্য প্রকারের অনুক্রমের সাথে চতুর হওয়া উচিত। এই সম্পর্কে আরও চিন্তা করে, আমি সিটিপিতে বিদ্যমান বাস্তবায়নটিকে যেমন আছে তেমন রাখব তবে এতে কিছুটা তুচ্ছ সংযোজন করব, যাতে আপনার await
কীওয়ার্ডটি স্পষ্টভাবে ব্যবহার করার প্রয়োজনের ক্ষেত্রে হ্রাস করতে পারে ।
আমরা একটি বৈশিষ্ট্য উদ্ভাবিত: [AutoAwait]
। এটি কেবল পদ্ধতিতে প্রয়োগ করা যেতে পারে। আপনার পদ্ধতিতে এটি প্রয়োগ করার একটি উপায় হ'ল এটি চিহ্নিত করা async
। তবে আপনি এটি হাতে করেও করতে পারেন, যেমন:
[AutoAwait]
public Task<Document> DownloadDocumentAsync()
তারপরে যে কোনও async
পদ্ধতির ভিতরেই , সংকলকটি ধরে নেবে যে আপনি কোনও কলটিতে অপেক্ষা করতে চান DownloadDocumentAsync
, তাই আপনাকে এটি নির্দিষ্ট করার দরকার নেই। এই পদ্ধতিতে যে কোনও কল স্বয়ংক্রিয়ভাবে এটির জন্য অপেক্ষা করবে।
Document doc = DownloadDocumentAsync();
এখন, আপনি যদি "চালাকি পেতে" এবং এটি পেতে চান Task<Document>
, আপনি একটি অপারেটর ব্যবহার করেন start
, যা কেবল কোনও পদ্ধতি কলের আগে উপস্থিত হতে পারে:
Task<Document> task = start DownloadDocumentAsync();
ঝরঝরে, আমি ভাবি। এখন একটি সরল পদ্ধতি কলটির অর্থ সাধারণত যা বোঝায়: পদ্ধতিটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করুন। এবং start
আলাদা কিছু নির্দেশ করে: অপেক্ষা করবেন না।
কোনও async
পদ্ধতির বাইরে উপস্থিত কোডের জন্য , আপনাকে কোনও [AutoAwait]
পদ্ধতিতে কল করার অনুমতি দেওয়া হচ্ছে কেবলমাত্র এটির সাথে উপসর্গ করে start
। এটি আপনাকে কোড লিখতে বাধ্য করে যা কোনও async
পদ্ধতিতে প্রদর্শিত হয় কিনা তা নির্বিশেষে একই অর্থ রয়েছে has
তারপরে আমি লোভ পেতে শুরু করি! :)
প্রথমত, আমি async
ইন্টারফেস পদ্ধতিতে প্রয়োগ করতে চাই :
interface IThing
{
async int GetCount();
}
মূলত এর অর্থ হ'ল বাস্তবায়ন পদ্ধতিটি অবশ্যই ফিরে আসবে Task<int>
বা এর সাথে সামঞ্জস্যপূর্ণ কিছু await
হবে এবং পদ্ধতিতে কলকারীরা [AutoAwait]
আচরণ পাবেন।
এছাড়াও আমি যখন উপরের পদ্ধতিটি প্রয়োগ করি তখন আমি লিখতে সক্ষম হতে চাই:
async int GetCount()
সুতরাং আমি Task<int>
রিটার্ন টাইপ হিসাবে উল্লেখ করতে হবে না ।
এছাড়াও, আমি async
প্রতিনিধি প্রকারগুলিতে প্রয়োগ করতে চাই (যা সর্বোপরি একটি পদ্ধতির ইন্টারফেসের মতো)। তাই:
public async delegate TResult AsyncFunc<TResult>();
একজন async
প্রতিনিধি আছে - আপনি এটি অনুমান করেছেন - [AutoAwait]
আচরণ। একটি async
পদ্ধতি থেকে আপনি এটিকে কল করতে পারেন এবং এটি স্বয়ংক্রিয়ভাবে await
এড হয়ে যাবে (যদি না আপনি কেবল start
এটি চয়ন করেন)। এবং তাই যদি আপনি বলেন:
AsyncFunc<Document> getDoc = DownloadDocumentAsync;
এটা ঠিক কাজ করে। এটি কোনও মেথড কল নয়। কোনও কাজ এখনও শুরু করা হয়নি - এটি কোনও কাজ async delegate
নয়। এটি কাজ করার জন্য একটি কারখানা। তুমি বলতে পারো:
Document doc = getDoc();
এবং এটি কোনও কাজ শুরু করবে এবং এটি শেষ হওয়ার জন্য অপেক্ষা করবে এবং আপনাকে ফলাফল দেবে। অথবা আপনি বলতে পারেন:
Task<Document> t = start getDoc();
সুতরাং এর মধ্যে একটি জায়গা যেখানে "নদীর গভীরতানির্ণয়" ফাঁস হয় তা হল আপনি যদি কোনও async
পদ্ধতিতে প্রতিনিধি বানাতে চান তবে আপনাকে কোনও async delegate
প্রকারটি ব্যবহার করতে হবে তা জানতে হবে । তার পরিবর্তে Func
আপনার অবশ্যই বলতে হবে AsyncFunc
, ইত্যাদি on যদিও একদিন সেই ধরণের জিনিসটি উন্নত প্রকারের অনুক্রমের মাধ্যমে স্থির করা যেতে পারে।
আর একটি প্রশ্ন হ'ল যদি আপনি কোনও সাধারণ (অ-অ্যাসিঙ্ক) পদ্ধতিতে শুরু করেন তবে কি হবে। অবশ্যই একটি সংকলন ত্রুটি হবে নিরাপদ বিকল্প। তবে অন্যান্য সম্ভাবনাও রয়েছে।