যেমনটি আপনি আবিষ্কার করেছেন, ভিএস 11-এ সংকলকটি কোনও async Main
পদ্ধতিকে অস্বীকার করবে । এটি এসিএনসি সিটিপি সহ ভিএস 2010 এ অনুমোদিত (তবে কখনও প্রস্তাবিত হয়নি)।
অ্যাসিঙ্ক / প্রতীক্ষা এবং বিশেষত অ্যাসিঙ্ক্রোনাস কনসোল প্রোগ্রাম সম্পর্কে আমার সাম্প্রতিক ব্লগ পোস্ট রয়েছে । ইন্ট্রো পোস্ট থেকে কিছু পটভূমি তথ্য এখানে:
যদি "অপেক্ষা" দেখেন যে অপেক্ষাগুলি সম্পন্ন হয়নি, তবে এটি অ্যাসিঙ্ক্রোনাসলি কাজ করে। এটি সম্পূর্ণ হওয়ার পরে পদ্ধতিটির বাকী অংশটি চালানোর জন্য অপেক্ষমানকে জানিয়ে দেয় এবং তারপরে অ্যাসিঙ্ক পদ্ধতি থেকে ফিরে আসে । পদ্ধতির বাকী অংশটি অপেক্ষারত পাস করার সময়ও ওউত বর্তমান প্রসঙ্গটি ক্যাপচার করবে ।
পরবর্তী সময়ে, যখন প্রতীক্ষিতটি সম্পূর্ণ হয়, এটি অ্যাসিঙ্ক পদ্ধতির বাকী অংশটি নির্ধারিত করবে (ধরা পড়া প্রসঙ্গে)।
কনসোল প্রোগ্রামগুলিতে এটি সহ একটি সমস্যা কেন তা এখানে রয়েছে async Main
:
আমাদের পরিচিতি পোস্ট থেকে মনে রাখবেন যে একটি অ্যাসিঙ্ক পদ্ধতিটি শেষ হওয়ার আগেই তার কলারে ফিরে আসবে । এটি ইউআই অ্যাপ্লিকেশনগুলিতে পুরোপুরি কাজ করে (পদ্ধতিটি কেবলমাত্র ইউআই ইভেন্ট লুপটিতে ফিরে আসে) এবং এএসপি.নেট অ্যাপ্লিকেশনগুলি (পদ্ধতিটি থ্রেড থেকে ফিরে আসে তবে অনুরোধটি জীবিত রাখে)। এটি কনসোল প্রোগ্রামগুলির জন্য এতটা ভাল কাজ করে না: ওএসে মূল রিটার্ন - যাতে আপনার প্রোগ্রামটি প্রস্থান হয়।
একটি সমাধান হ'ল আপনার নিজস্ব প্রসঙ্গ সরবরাহ করা - আপনার কনসোল প্রোগ্রামের জন্য একটি "প্রধান লুপ" যা অ্যাসিঙ্ক-সামঞ্জস্যপূর্ণ।
আপনার যদি অ্যাসিঙ্ক সিটিপি সহ কোনও মেশিন থাকে তবে আপনি আমার ডকুমেন্টস \ মাইক্রোসফ্ট ভিজ্যুয়াল স্টুডিও অ্যাসিঙ্ক সিটিপি \ নমুনা (সি # টেস্টিং) ইউনিট টেস্টিং \ অ্যাসিঙ্কটেষ্ট ইউটিলিটিগুলিGeneralThreadAffineContext
থেকে ব্যবহার করতে পারেন । বিকল্পভাবে, আপনি আমার নিতো.অ্যাক্সেক্স এক্স নিউগেট প্যাকেজটি থেকে ব্যবহার করতে পারেন ।AsyncContext
এখানে ব্যবহার করে একটি উদাহরণ দেওয়া হয়েছে AsyncContext
; GeneralThreadAffineContext
প্রায় অভিন্ন ব্যবহার আছে:
using Nito.AsyncEx;
class Program
{
static void Main(string[] args)
{
AsyncContext.Run(() => MainAsync(args));
}
static async void MainAsync(string[] args)
{
Bootstrapper bs = new Bootstrapper();
var list = await bs.GetList();
}
}
বিকল্পভাবে, আপনার অ্যাসিক্রোনাস কাজ শেষ না হওয়া পর্যন্ত আপনি কেবলমাত্র মূল কনসোল থ্রেডটি ব্লক করতে পারেন:
class Program
{
static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
static async Task MainAsync(string[] args)
{
Bootstrapper bs = new Bootstrapper();
var list = await bs.GetList();
}
}
এর ব্যবহারটি নোট করুন GetAwaiter().GetResult()
; এটি AggregateException
যদি আপনি ব্যবহার করেন Wait()
বা করেন তবে মোড়ক এড়ানো যায় Result
।
আপডেট, 2017-11-30: ভিজ্যুয়াল স্টুডিও 2017 আপডেট 3 (15.3) হিসাবে, ভাষা এখন একটি সমর্থন করে async Main
- যতক্ষণ না এটি ফিরে আসে Task
বা আসে Task<T>
। সুতরাং আপনি এখন এটি করতে পারেন:
class Program
{
static async Task Main(string[] args)
{
Bootstrapper bs = new Bootstrapper();
var list = await bs.GetList();
}
}
শব্দার্থকগুলি GetAwaiter().GetResult()
মূল থ্রেডটি ব্লক করার শৈলীর মতো দেখা যায় । তবে, সি # 7.1 এর জন্য এখনও কোনও ভাষার অনুমান নেই, সুতরাং এটি কেবলমাত্র অনুমান।