আমি মনে করি আপনি এখানে কিছু জিনিস বিভ্রান্ত করছেন। আপনি যা জিজ্ঞাসা করছেন তা ইতিমধ্যে ব্যবহার করা সম্ভব System.Threading.Tasks
, async
এবং await
সি # 5 এ একই বৈশিষ্ট্যের জন্য সামান্য উত্তম সিনট্যাকটিক চিনি সরবরাহ করতে চলেছে।
আসুন একটি উইনফর্ম উদাহরণ ব্যবহার করুন - ফর্মটিতে একটি বোতাম এবং একটি পাঠ্যবক্স ফেলে দিন এবং এই কোডটি ব্যবহার করুন:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew<int>(() => DelayedAdd(5, 10))
.ContinueWith(t => DelayedAdd(t.Result, 20))
.ContinueWith(t => DelayedAdd(t.Result, 30))
.ContinueWith(t => DelayedAdd(t.Result, 50))
.ContinueWith(t => textBox1.Text = t.Result.ToString(),
TaskScheduler.FromCurrentSynchronizationContext());
}
private int DelayedAdd(int a, int b)
{
Thread.Sleep(500);
return a + b;
}
এটি চালান এবং আপনি দেখতে পাবেন যে (ক) এটি ইউআই থ্রেডটিকে অবরুদ্ধ করে না এবং (খ) আপনি স্বাভাবিক "ক্রস-থ্রেড অপারেশনটি বৈধ নয়" ত্রুটিটি পাবেন না - যদি আপনি TaskScheduler
শেষ থেকে যুক্তিটি সরিয়ে ContinueWith
না ফেলে কোন ক্ষেত্রে আপনি হবে।
এটি বগ-স্ট্যান্ডার্ড ধারাবাহিকতা পাসিং স্টাইল । ম্যাজিকটি TaskScheduler
ক্লাসে ঘটে এবং বিশেষত উদাহরণটি পুনরুদ্ধার করে FromCurrentSynchronizationContext
। এটি কোনও ধারাবাহিকতায় পাস করুন এবং আপনি এটিকে বলবেন যে ধারাবাহিকতা অবশ্যই যাকে বলা যাক থ্রেডে চলতে হবে FromCurrentSynchronizationContext
- এই ক্ষেত্রে, ইউআই থ্রেড।
অপহরণকারীরা এই ধারনায় কিছুটা পরিশীলিত যে তারা কোন থ্রেড শুরু করেছে এবং কোন থ্রেডটিতে ধারাবাহিকতাটি হওয়া উচিত তা সম্পর্কে তারা সচেতন। সুতরাং উপরের কোডটি আরও কিছুটা স্বাভাবিকভাবে লেখা যেতে পারে :
private async void button1_Click(object sender, EventArgs e)
{
int a = await DelayedAddAsync(5, 10);
int b = await DelayedAddAsync(a, 20);
int c = await DelayedAddAsync(b, 30);
int d = await DelayedAddAsync(c, 50);
textBox1.Text = d.ToString();
}
private async Task<int> DelayedAddAsync(int a, int b)
{
Thread.Sleep(500);
return a + b;
}
এই দুটি অনুরূপ হওয়া উচিত, এবং আসলে তারা হয় খুব অনুরূপ। DelayedAddAsync
পদ্ধতি এখন একটি ফেরৎ Task<int>
একটি পরিবর্তে int
, এবং তাই await
কেবলমাত্র সেই প্রতিটি সম্মুখের continuations slapping হয়। মূল পার্থক্যটি হ'ল এটি প্রতিটি লাইনের সিঙ্ক্রোনাইজেশন প্রসঙ্গে চলেছে, সুতরাং আপনাকে শেষের উদাহরণে যেমনটি করা হয়েছিল তেমনভাবে আপনাকে তা করতে হবে না।
তত্ত্বগতভাবে পার্থক্যগুলি আরও অনেক তাৎপর্যপূর্ণ। দ্বিতীয় উদাহরণে, button1_Click
পদ্ধতিটির প্রতিটি একক লাইন আসলে ইউআই থ্রেডে চালিত হয় তবে টাস্কটি নিজেই ( DelayedAddAsync
) পটভূমিতে চলে। প্রথম উদাহরণে, সবকিছু রানে পটভূমি , ছাড়া নিয়োগ করার জন্য textBox1.Text
যা আমরা স্পষ্টভাবে UI 'তে থ্রেড এর সিঙ্ক্রোনাইজেশন প্রসঙ্গে সংযুক্ত করেছি।
এটিই সম্পর্কে আকর্ষণীয় যা await
- একটি প্রতীক্ষক কোনও ব্লকিং কল ছাড়াই একই পদ্ধতিতে ঝাঁপিয়ে পড়তে সক্ষম । আপনি কল করেছেন await
, বর্তমান থ্রেড বার্তাগুলি প্রসেসিংয়ে ফিরে গেছে এবং এটি শেষ হয়ে গেলে ওয়েটারটি যেখানে ছেড়ে গেছে ঠিক সেখানেই নেবে, একই থ্রেডে এটি যেভাবে ছেড়েছিল the তবে প্রশ্নটিতে আপনার Invoke
/ BeginInvoke
বিপরীতে আমি, দুঃখের সাথে জানাচ্ছি যে আপনি অনেক আগে এই কাজটি করা বন্ধ করে দিয়েছিলেন।
await
উদ্বিগ্ন হওয়ায় অন্তত ইনসফার । ধারাবাহিকতা কেটে যাওয়ার জন্য এটি প্রচুর সিনট্যাকটিক চিনি । সম্ভবত উইনফর্মগুলিতে কিছু অপ্রাসঙ্গিক উন্নতি আছে যেগুলি সাহায্য করার কথা রয়েছে? এটি নিজেই নেট নেট ফ্রেমওয়ার্কের আওতায় পড়বে, যদিও বিশেষত সি # নয়।