সি # 5 অ্যাসিঙ্ক সমর্থন কীভাবে ইউআই থ্রেড সিঙ্ক্রোনাইজেশন সমস্যাগুলিতে সহায়তা করবে?


16

আমি কোথাও শুনেছি যে সি # 5 অ্যাসিঙ্ক-প্রতীক্ষা এতটাই দুর্দান্ত হবে যে আপনাকে এটি করার বিষয়ে চিন্তা করতে হবে না:

if (InvokeRequired)
{
    BeginInvoke(...);
    return;
}
// do your stuff here

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

আমি মনে করি যে এই জাতীয় বৈশিষ্ট্যটির একটি সাধারণ ব্যবহার এই জাতীয় কিছু হবে:

public class Form1 : Form
{
    // ...
    async void GetFurtherInfo()
    {
        var temperature = await GetCurrentTemperatureAsync();
        label1.Text = temperature;
    }
}

যদি কেবলমাত্র একটি কলব্যাক ব্যবহৃত হয় তবে লেবেল পাঠ্যটি সেট করা একটি ব্যতিক্রম বাড়াবে কারণ এটি ইউআই থ্রেডে কার্যকর করা হচ্ছে না।

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

দয়া করে একটি নির্ভরযোগ্য উত্স থেকে একটি লিঙ্ক সরবরাহ করুন, কেবল "হ্যাঁ" এর উত্তর দিবেন না।


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

@ অ্যারোনআট আমি সম্মত, এই কারণেই আমি প্রশ্নটি যথাযথভাবে জিজ্ঞাসা করছি। আমি কোথা থেকে আসছি তা পরিষ্কার করতে আমি প্রশ্নটি সম্পাদনা করেছি। অদ্ভুত শোনায় যে তারা এই বৈশিষ্ট্যটি তৈরি করবে এবং তারপরেও আমাদের প্রয়োজন কুখ্যাত ইনভোকেরইকায়ার্ড স্টাইলের কোডটি ব্যবহার করা।
অ্যালেক্স

উত্তর:


17

আমি মনে করি আপনি এখানে কিছু জিনিস বিভ্রান্ত করছেন। আপনি যা জিজ্ঞাসা করছেন তা ইতিমধ্যে ব্যবহার করা সম্ভব 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বিপরীতে আমি, দুঃখের সাথে জানাচ্ছি যে আপনি অনেক আগে এই কাজটি করা বন্ধ করে দিয়েছিলেন।


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

1
@ অ্যালেক্স: এই সমস্ত ফলো-আপ প্রশ্নের উত্তরগুলির জন্য, আমি আপনাকে অ্যাসিঙ্ক পারফরম্যান্স পড়ার পরামর্শ দিচ্ছি : অ্যাসিঙ্ক এবং অ্যাওয়েটের ব্যয় বোঝা । "বিষয়বস্তু যত্ন সম্পর্কে" বিভাগটি কীভাবে এটি সমস্ত সিঙ্ক্রোনাইজেশন প্রসঙ্গে সম্পর্কিত।
অ্যারোনআউট

(উপায় দ্বারা, সিঙ্ক্রোনাইজেশন প্রেক্ষিতে নতুন নয়; তারা কাঠামোর মধ্যে 2.0 যেহেতু চলেছি TPL শুধু তাদের ব্যবহার করার জন্য অনেক সহজ করেছে।।)
Aaronaught

2
আমি ভাবছি কেন ইনভোকেরইকায়ার্ড স্টাইলটি ব্যবহার করার বিষয়ে কেন অনেক আলোচনা চলছে এবং আমি দেখেছি বেশিরভাগ থ্রেড এমনকি সিঙ্ক প্রসঙ্গগুলিও উল্লেখ করে না। এই প্রশ্নটি
অ্যালেক্স

2
@Alex: আমি অনুমান তুমি করা হয় নি ঠিক জায়গায় খুঁজছি । তোমাকে কী বলব জানি না; .NET সম্প্রদায়ের বড় অংশ রয়েছে যা ধরতে দীর্ঘ সময় নেয়। হেল, আমি এখনও ArrayListনতুন কোডে ক্লাস ব্যবহার করে কিছু কোডার দেখতে পাচ্ছি । আমি নিজেও আরএক্সের সাথে সবেমাত্র কোনও অভিজ্ঞতা পেয়েছি। লোকেরা তাদের যা জানার প্রয়োজন এবং যা তারা ইতিমধ্যে জানে তা ভাগ করে নেবে, যদিও তারা ইতিমধ্যে জানে তা পুরানো হয়ে গেছে। এই উত্তর কয়েক বছরের মধ্যে পুরানো হতে পারে।
অ্যারোনআউট

4

হ্যাঁ, ইউআই থ্রেডের জন্য, অপেক্ষা করা অপারেশনের কলব্যাক কলারের মূল থ্রেডে ঘটবে।

এরিক লিপার্ট এক বছর আগে এটি নিয়ে একটি 8-অংশের সিরিজ লিখেছিলেন: কোডিংয়ে ফ্যাবুলাস অ্যাডভেঞ্চারস

সম্পাদনা: এবং এখানে এন্ডার্সের // বিল্ড / উপস্থাপনা: চ্যানেল 9

বিটিডাব্লু, আপনি কি লক্ষ্য করেছেন যে আপনি যদি "// বিল্ড /" উল্টে পরিণত করেন তবে আপনি "/ plinq //" পাবেন ;-)


3

জন স্কিটি সি # 5 তে অ্যাসিঙ্ক পদ্ধতিগুলি কভার করে একটি দুর্দান্ত উপস্থাপনা দিয়েছিল যা আপনি অত্যন্ত কার্যকর বলে মনে করতে পারেন:

http://skillsmatter.com/podcast/home/async-methods


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