সিঙ্ক্রোনাইজেশন কনটেক্সট কী করে?


135

প্রোগ্রামিং সি # বইটিতে এর কয়েকটি নমুনা কোড রয়েছে SynchronizationContext:

SynchronizationContext originalContext = SynchronizationContext.Current;
ThreadPool.QueueUserWorkItem(delegate {
    string text = File.ReadAllText(@"c:\temp\log.txt");
    originalContext.Post(delegate {
        myTextBox.Text = text;
    }, null);
});

আমি থ্রেডে একটি শিক্ষানবিস, সুতরাং দয়া করে বিস্তারিত উত্তর দিন। প্রথমত, আমি জানিনা প্রসঙ্গে কী বোঝায়, প্রোগ্রামটি এর মধ্যে originalContextকী সংরক্ষণ করে ? এবং যখন Postপদ্ধতিটি বরখাস্ত করা হয়, তখন ইউআই থ্রেডটি কী করবে?
আমি যদি কিছু নির্বোধ জিনিস জিজ্ঞাসা করি, দয়া করে আমাকে সংশোধন করুন, ধন্যবাদ!

সম্পাদনা: উদাহরণস্বরূপ, আমি যদি কেবল myTextBox.Text = text;পদ্ধতিতে লিখি তবে পার্থক্য কী?


1
সূক্ষ্ম ম্যানুয়ালটিতে এই কথাটি বলা আছে যে এই শ্রেণীর দ্বারা বাস্তবায়িত সিঙ্ক্রোনাইজেশন মডেলের উদ্দেশ্য হ'ল সাধারণ ভাষা রানটাইমের অভ্যন্তরীণ অ্যাসিনক্রোনাস / সিঙ্ক্রোনাইজেশন অপারেশনগুলিকে বিভিন্ন সিঙ্ক্রোনাইজেশন মডেলের সাথে সঠিকভাবে আচরণ করতে দেওয়া। এই মডেলটি বিভিন্ন সিঙ্ক্রোনাইজেশন পরিবেশের অধীনে সঠিকভাবে কাজ করার জন্য পরিচালিত অ্যাপ্লিকেশনগুলিকে অনুসরণ করতে হয়েছিল এমন কয়েকটি প্রয়োজনীয়তাও সহজ করে।
ta.speot.is

আইএমএইচও
অ্যাসিঙ্ক

7
@ রইনিমির: হ্যাঁ, তবে অনুমান করুন: async/ নীচে কীভাবে awaitনির্ভর করে SynchronizationContext
স্টাকেক্স -

উত্তর:


170

সিঙ্ক্রোনাইজেশন কনটেক্সট কী করে?

সহজ ভাষায় বলা যায়, এমন SynchronizationContextএকটি অবস্থান উপস্থাপন করে যেখানে "কোড" কোড কার্যকর করা হতে পারে। তার প্রতিনিধি Sendবা Postপদ্ধতিতে পাস করা প্রতিনিধিদের সেই স্থানে ডাকা হবে। ( Postএটি অ-ব্লকিং / অ্যাসিঙ্ক্রোনাস সংস্করণ Send।)

প্রতিটি থ্রেড এর SynchronizationContextসাথে সম্পর্কিত উদাহরণ থাকতে পারে। চলমান থ্রেড স্থির SynchronizationContext.SetSynchronizationContextপদ্ধতিতে কল করে একটি সিঙ্ক্রোনাইজেশন প্রসঙ্গে যুক্ত হতে পারে এবং চলমান থ্রেডের বর্তমান প্রসঙ্গটি SynchronizationContext.Currentসম্পত্তিটির মাধ্যমে অনুসন্ধান করা যেতে পারে ।

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

উইন্ডোজ ফর্মগুলি WindowsFormsSynchronizationContextযে থ্রেডে প্রথম ফর্ম তৈরি হবে সেখানে একটি ইনস্টল করবে । (এই থ্রেডটি সাধারণত "ইউআই থ্রেড" নামে পরিচিত) এটি অন্যান্য ইউআই ফ্রেমওয়ার্কগুলির মতো উইন্ডোজ ফর্মগুলি কেবল একই থ্রেডের উপর নিয়ন্ত্রণের কারসাজির অনুমতি দেয় যার ফলে তারা তৈরি হয়েছিল This

আমি যদি কেবল myTextBox.Text = text;পদ্ধতিতে লিখি তবে পার্থক্য কী?

আপনি যে কোডটি পাস করেছেন তা ThreadPool.QueueUserWorkItemথ্রেড পুল কর্মী থ্রেডে চালিত হবে। এটি হ'ল এটি যে থ্রেডটিতে আপনার myTextBoxতৈরি হয়েছিল তাতে চালিত হবে না , সুতরাং উইন্ডোজ ফর্মগুলি শীঘ্রই বা পরে (বিশেষত রিলিজ বিল্ডগুলিতে) একটি ব্যতিক্রম ছুঁড়ে দেবে, আপনাকে বলবে যে আপনি myTextBoxঅন্য থ্রেড থেকে অ্যাক্সেস নাও করতে পারেন ।

এজন্য আপনাকে myTextBoxসেই নির্দিষ্ট কার্যভারের আগে কোনওভাবে কর্মী থ্রেড থেকে "ইউআই থ্রেড" (যেখানে তৈরি করা হয়েছিল) যেতে হবে। এটি নিম্নলিখিত হিসাবে সম্পন্ন করা হয়:

  1. আপনি এখনও ইউআই থ্রেডে থাকাকালীন SynchronizationContextসেখানে উইন্ডোজ ফর্মগুলি ক্যাপচার করুন এবং originalContextপরবর্তী ব্যবহারের জন্য ভেরিয়েবল ( ) এ এটির একটি রেফারেন্স সঞ্চয় করুন । SynchronizationContext.Currentএই মুহুর্তে আপনার অবশ্যই জিজ্ঞাসা করা উচিত ; যদি আপনি কোডটি পাসের ভিতরে এটি জিজ্ঞাসা করে থাকেন তবে আপনি ThreadPool.QueueUserWorkItemথ্রেড পুলের কর্মী থ্রেডের সাথে সম্পর্কিত যে কোনও সিঙ্ক্রোনাইজেশন প্রসঙ্গটি পেতে পারেন। আপনি একবার উইন্ডোজ ফর্মগুলির প্রসঙ্গে একটি রেফারেন্স সঞ্চয় করে রাখলে, আপনি ইউআই থ্রেডে কোড "প্রেরণ" করতে যে কোনও জায়গায় এবং যে কোনও সময় এটি ব্যবহার করতে পারেন।

  2. যখনই আপনি UI 'তে উপাদান নিপূণভাবে করতে হবে (কিন্তু UI' তে থ্রেডে আর, অথবা নাও হতে পারে) মাধ্যমে, অ্যাক্সেস উইন্ডোজ ফরম 'সিঙ্ক্রোনাইজেশন প্রসঙ্গ originalContext, এবং হাত কোড বন্ধ যে পারেন UI' তে নিপূণভাবে হবে Sendবা Post


চূড়ান্ত মন্তব্য এবং ইঙ্গিত:

  • কোন সিঙ্ক্রোনাইজেশন প্রসঙ্গ আপনার জন্য না করবে তা আপনাকে জানিয়ে দিচ্ছে কোন কোডটি কোনও নির্দিষ্ট স্থান / প্রসঙ্গে চালানো উচিত এবং কোন কোডটি এটিকে পাস না করে কেবলমাত্র কার্যকর করা যেতে পারে SynchronizationContext। এটি সিদ্ধান্ত নেওয়ার জন্য, আপনি যে ফ্রেমওয়ার্কটির বিরুদ্ধে প্রোগ্রামিং করছেন তার বিধি ও প্রয়োজনীয়তা অবশ্যই আপনাকে জানতে হবে - এই ক্ষেত্রে উইন্ডোজ ফর্মগুলি।

    সুতরাং উইন্ডোজ ফর্মগুলির জন্য এই সহজ নিয়মটি মনে রাখবেন: সেগুলি তৈরি করা ব্যতীত অন্য কোনও থ্রেড থেকে নিয়ন্ত্রণ বা ফর্মগুলি অ্যাক্সেস করবেন না। আপনার যদি এটি করতেই হয় তবে SynchronizationContextউপরে বর্ণিত পদ্ধতিটি ব্যবহার করুন বা Control.BeginInvoke(যা একই পদ্ধতিতে উইন্ডোজ ফর্ম-নির্দিষ্ট পদ্ধতি)।

  • আপনি বা .NET 4.5 বিরুদ্ধে পরবর্তী করছি প্রোগ্রামিং, তাহলে আপনি আপনার কোডটি স্পষ্টভাবে রূপান্তর আপনার জীবনে অনেক সহজ করে তুলতে পারে ব্যবহারসমূহ SynchronizationContext, ThreadPool.QueueUserWorkItem, control.BeginInvoke, ইত্যাদি নতুন ওভার async/ awaitকিওয়ার্ড এবং টাস্ক সমান্তরাল লাইব্রেরি (TPL) , অর্থাত্ পার্শ্ববর্তী এপিআই The Taskএবং Task<TResult>ক্লাস। এগুলি, খুব উচ্চ ডিগ্রী পর্যন্ত, ইউআই থ্রেডের সিঙ্ক্রোনাইজেশন প্রসঙ্গে ক্যাপচার করার ব্যবস্থা গ্রহণ করবে, একটি অ্যাসিঙ্ক্রোনাস অপারেশন শুরু করবে, এবং আবার ইউআই থ্রেডে ফিরে আসবে যাতে আপনি অপারেশনের ফলাফলটি প্রক্রিয়া করতে পারেন।


আপনি বলছেন যে উইন্ডোজ ফর্মগুলি অন্যান্য অনেকগুলি ইউআই ফ্রেমওয়ার্কের মতোই কেবল একই থ্রেডে নিয়ন্ত্রণের কারসাজির অনুমতি দেয় তবে উইন্ডোজের সমস্ত উইন্ডো অবশ্যই এটি তৈরি করে একই থ্রেড দ্বারা অ্যাক্সেস করতে হবে।
ব্যবহারকারী 34660

4
@ ব্যবহারকারী 34660: না, এটি সঠিক নয়। আপনি করতে পারেন একাধিক থ্রেড যে উইন্ডোজ ফরম নিয়ন্ত্রণ তৈরি আছে। তবে প্রতিটি নিয়ন্ত্রণ এটি তৈরি করা একটি থ্রেডের সাথে সম্পর্কিত এবং কেবল একটি থ্রেড দ্বারা অ্যাক্সেস করতে হবে। বিভিন্ন ইউআই থ্রেডের নিয়ন্ত্রণগুলি একে অপরের সাথে কীভাবে যোগাযোগ করে তার মধ্যেও খুব সীমাবদ্ধ: একজন অন্যের পিতামাতা / সন্তানের হতে পারে না, তাদের মধ্যে ডেটা বাঁধাই সম্ভব নয় ইত্যাদি etc. পরিশেষে, নিয়ন্ত্রণগুলি তৈরি করে এমন প্রতিটি থ্রেডের নিজস্ব বার্তা প্রয়োজন লুপ (যা Application.Runআইআইআরসি দ্বারা শুরু হয় )। এটি মোটামুটি উন্নত একটি বিষয় এবং এটি ঘটনাক্রমে কিছু হয়নি not
স্টাকেক্স -

আমার প্রথম মন্তব্যটি আপনার "অন্যান্য অনেকগুলি ইউআই ফ্রেমওয়ার্কের মতো" বলার কারণেই বোঝানো হয়েছে যে কিছু উইন্ডো " থ্রেড কন্ট্রোলের" আলাদা থ্রেড থেকে অনুমতি দেয় তবে উইন্ডোজ কোনও উইন্ডোজ দেয় না। একই উইন্ডোর জন্য আপনার "বেশ কয়েকটি থ্রেড থাকতে পারে না যা উইন্ডোজ ফর্ম নিয়ন্ত্রণগুলি তৈরি করে" এবং "একই থ্রেড দ্বারা অ্যাক্সেস করতে হবে" এবং "একই থ্রেড দ্বারা কেবল অ্যাক্সেস করতে হবে" একই কথা বলছে। আমি সন্দেহ করি যে একই উইন্ডোর জন্য "বিভিন্ন ইউআই থ্রেড থেকে নিয়ন্ত্রণ" তৈরি করা সম্ভব। আমাদের সবার জন্য উইন্ডোজ প্রোগ্রামিংয়ের অভিজ্ঞতা থাকা তাদের জন্য এই সমস্ত কিছুই উন্নত নয় et নেট।
ব্যবহারকারী 34660

3
"উইন্ডোজ" এবং "উইন্ডোজ উইন্ডোজ" সম্পর্কে এই সমস্ত আলোচনা আমাকে বরং চঞ্চল করে তুলছে। আমি কি এই "উইন্ডো" এর কোনও উল্লেখ করেছি? আমি মনে করি না ...
স্ট্যাকেক্স -

1
@ আইবিবি: আমি নিশ্চিত না যে আমি আপনার প্রশ্নটি বুঝতে পেরেছি। যে কোনও থ্রেডের সিঙ্ক্রোনাইজেশন প্রসঙ্গটি সেট হয় না ( null) বা একটি উদাহরণ SynchronizationContext(বা এটির একটি সাবক্লাস)। এই উক্তিটির মূল বক্তব্যটি আপনি যা পান তা নয়, তবে আপনি কী পাবেন না : ইউআই থ্রেডের সিঙ্ক্রোনাইজেশন প্রসঙ্গ।
স্টাকেক্স -

24

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

আপনি যদি উইন 32 প্রোগ্রামিং মডেলের সাথে পরিচিত হন তবে খুব ঘনিষ্ঠ সাদৃশ্যটি হবে PostMessageএবং SendMessageএপিআই, যা আপনি লক্ষ্য উইন্ডোটির থেকে আলাদা থ্রেড থেকে কোনও বার্তা প্রেরণের জন্য কল করতে পারেন।

সিঙ্ক্রোনাইজেশন প্রসঙ্গগুলি কী তা সম্পর্কে খুব ভাল ব্যাখ্যা এখানে দেওয়া হয়েছে: এটি সিঙ্ক্রোনাইজেশন কনটেক্সট সম্পর্কিত সমস্ত বিষয়


16

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

স্নিপেটে ব্যবহৃত থ্রেড-পুল থ্রেডের মতো আপনি যখন অন্য থ্রেডে কোড চালাচ্ছেন, তখন আপনাকে সতর্কতা অবলম্বন করতে হবে যে আপনি থ্রেড-অনিরাপদযুক্ত বস্তুগুলি সরাসরি ব্যবহার করবেন না। যে কোনও ব্যবহারকারীর ইন্টারফেস অবজেক্টের মতো, আপনাকে অবশ্যই পাঠ্যবক্সটি তৈরি করা থ্রেড থেকে টেক্সটবক্স.প্রযুক্তি সম্পত্তিটি আপডেট করতে হবে। পোস্ট () পদ্ধতিটি নিশ্চিত করে যে প্রতিনিধি লক্ষ্যটি সেই থ্রেডে চলে।

সাবধান থাকুন যে এই স্নিপেটটি কিছুটা বিপজ্জনক, আপনি যখন ইউআই থ্রেড থেকে কল করবেন তখনই এটি সঠিকভাবে কাজ করবে। সিঙ্ক্রোনাইজেশন কনটেক্সট.কেনটের বিভিন্ন থ্রেডে বিভিন্ন মান রয়েছে। কেবলমাত্র ইউআই থ্রেডের একটি ব্যবহারযোগ্য মান রয়েছে। এবং কোডটি এটি অনুলিপি করার কারণ ছিল। একটি উইনফর্মস অ্যাপ্লিকেশনে এটি করার আরও একটি পঠনযোগ্য এবং নিরাপদ উপায়:

    ThreadPool.QueueUserWorkItem(delegate {
        string text = File.ReadAllText(@"c:\temp\log.txt");
        myTextBox.BeginInvoke(new Action(() => {
            myTextBox.Text = text;
        }));
    });

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

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


আমি দুঃখিত, ইউআই থ্রেড হ্যান্ডেলটি কেন থ্রেড-নিরাপদ হতে দিন? অর্থাৎ আমি মনে করি ইউআই থ্রেডটি মাই টেক্সটবক্স ব্যবহার করতে পারে যখন পোস্ট () গুলি ছুঁড়েছে, তা কি নিরাপদ?
মেঘলা ফ্যান

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

5

এখানে সিঙ্ক্রোনাইজেশন প্রসঙ্গে উদ্দেশ্যটি নিশ্চিত করা হয় যে myTextbox.Text = text;এটি ইউআই থ্রেডে ডেকেছে।

উইন্ডোজের প্রয়োজন যে জিইউআই নিয়ন্ত্রণগুলি কেবল তাদের দ্বারা নির্মিত থ্রেড দ্বারা অ্যাক্সেস করা উচিত। আপনি যদি প্রথম সিঙ্ক্রোনাইজ না করে পটভূমির থ্রেডটিতে পাঠ্যটিকে নির্ধারিত করার চেষ্টা করেন (বেশ কয়েকটি মাধ্যমে যেমন এটি বা ইনভোক প্যাটার্ন) তবে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হবে।

এটি যা করে তা হ'ল ব্যাকগ্রাউন্ড থ্রেড তৈরি করার আগে সিঙ্ক্রোনাইজেশন প্রসঙ্গটি সংরক্ষণ করে, তারপরে পটভূমি থ্রেডটি প্রসঙ্গটি ব্যবহার করে ost পোস্ট পদ্ধতিটি জিইউআই কোড চালায়।

হ্যাঁ, আপনার প্রদর্শিত কোডটি মূলত অকেজো use ব্যাকগ্রাউন্ড থ্রেড কেন তৈরি করবেন, কেবল তাত্ক্ষণিকভাবে মূল ইউআই থ্রেডে ফিরে যেতে হবে? এটি কেবল একটি উদাহরণ।


4
"হ্যাঁ, আপনি যে কোডটি দেখিয়েছেন তা মূলত অকেজো। কেন পটভূমি থ্রেড তৈরি করবেন, কেবল তাত্ক্ষণিকভাবে মূল ইউআই থ্রেডে ফিরে যেতে হবে? এটি কেবল উদাহরণ।" - ফাইলটি পড়া খুব বড় কাজ হতে পারে যদি ফাইলটি বড় হয়, এমন কিছু যা ইউআই থ্রেডকে ব্লক করে এবং এটিকে প্রতিক্রিয়াহীন করে তুলতে পারে
ইয়ায়ার নেভেট

আমি একটি বোকা প্রশ্ন আছে। প্রতিটি থ্রেডের একটি আইডি রয়েছে এবং আমি মনে করি যে ইউআই থ্রেডেরও একটি আইডি = 2 রয়েছে উদাহরণস্বরূপ। তারপরে, যখন আমি থ্রেড পুলের থ্রেডে থাকি, তখন আমি কি তেমন কিছু করতে পারি: var থ্রেড = গেটথ্রেড (2); থ্রেড.এক্সেকিউট (() => টেক্সটবক্স 1. পাঠ্য = "ফু")?
জন

@ জন - না, আমি মনে করি না যে এটি কাজ করে কারণ থ্রেড ইতিমধ্যে কার্যকর করা হচ্ছে। আপনি ইতিমধ্যে কার্যকর করা থ্রেড কার্যকর করতে পারবেন না। কোনও থ্রেড চলমান না
থাকলেই কার্যকর করুন

3

উত্স থেকে

প্রতিটি থ্রেডের সাথে এটি সম্পর্কিত একটি প্রসঙ্গ রয়েছে - এটি "বর্তমান" প্রসঙ্গ হিসাবেও পরিচিত - এবং এই প্রসঙ্গগুলি থ্রেডে ভাগ করা যায়। এক্সিকিউশন কনটেক্সটটিতে বর্তমান পরিবেশ বা প্রসঙ্গে প্রাসঙ্গিক কর্মসূচির প্রাসঙ্গিক মেটাডেটা রয়েছে। সিঙ্ক্রোনাইজেশন কনটেক্সট একটি বিমূর্ততা উপস্থাপন করে - এটি আপনার অ্যাপ্লিকেশনটির কোডটি কার্যকর করা হয় এমন জায়গাকে বোঝায়।

একটি সিঙ্ক্রোনাইজেশন কনটেক্সট আপনাকে অন্য প্রসঙ্গে একটি টাস্কের সারি তৈরি করতে সক্ষম করে। নোট করুন যে প্রতিটি থ্রেডের নিজস্ব সিঙ্ক্রোনাইজাটোন কনটেক্সট থাকতে পারে।

উদাহরণস্বরূপ: ধরুন আপনার দুটি থ্রেড, থ্রেড 1 এবং থ্রেড 2 রয়েছে। বলুন, থ্রেডড 1 কিছু কাজ করছে এবং তারপরে থ্রেড 1 থ্রেড 2-তে কোড সম্পাদন করতে চায়। এটি করার একটি সম্ভাব্য উপায় থ্রেড 2 কে তার সিঙ্ক্রোনাইজেশন কনটেক্সট অবজেক্টের জন্য জিজ্ঞাসা করা, থ্রেডড 1 এ দিন এবং তারপরে থ্রেড 1 সিঙ্ক্রোনাইজেশন কনটেক্সটকে কল করতে পারে Th থ্রেড 2-তে কোডটি কার্যকর করতে পাঠান।


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

3

সিঙ্ক্রোনাইজেশন কনটেক্সট আমাদের বিভিন্ন থ্রেড থেকে ইউআই আপডেট করার একটি উপায় সরবরাহ করে (সমকালীনভাবে প্রেরণ পদ্ধতিটির মাধ্যমে বা পোস্ট পদ্ধতির মাধ্যমে অ্যাসিক্রোনারলি)।

নিম্নলিখিত উদাহরণটি একবার দেখুন:

    private void SynchronizationContext SyncContext = SynchronizationContext.Current;
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Thread thread = new Thread(Work1);
        thread.Start(SyncContext);
    }

    private void Work1(object state)
    {
        SynchronizationContext syncContext = state as SynchronizationContext;
        syncContext.Post(UpdateTextBox, syncContext);
    }

    private void UpdateTextBox(object state)
    {
        Thread.Sleep(1000);
        string text = File.ReadAllText(@"c:\temp\log.txt");
        myTextBox.Text = text;
    }

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

private void Button_Click(object sender, RoutedEventArgs e) 
{
    Thread.Sleep(1000);
    string text = File.ReadAllText(@"c:\temp\log.txt");
    myTextBox.Text = text;
}

শেষ উদাহরণ এবং এটি একটি কার্যকর করে। উভয়ই ইউআই-কে কাজ করার সময় অবরুদ্ধ করে না।

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

আশা করি এটি আপনাকে সহায়তা করবে, সাথী!


2

সিঙ্ক্রোনাইজেশন কনটেক্সট মূলত কলব্যাক প্রতিনিধিদের মৃত্যুদন্ড কার্যকর করে এমন একটি প্রোগ্রাম যার মাধ্যমে একটি প্রোগ্রামের কোডের একটি নির্দিষ্ট অংশ (। নেট টিপিএল এর একটি টাস্ক অবজেক্টে অন্তর্ভুক্ত) এর কার্য সম্পাদন সম্পন্ন হওয়ার পরে এটি প্রদত্ত নির্বাহের প্রেক্ষাপটে চালানো হয় তা নিশ্চিত করার জন্য দায়বদ্ধ ।

প্রযুক্তিগত দৃষ্টিকোণ থেকে, এসসি হ'ল একটি সাধারণ সি # শ্রেণি যা কার্যত সমান্তরাল লাইব্রেরি অবজেক্টের জন্য বিশেষভাবে এর ক্রিয়াকলাপটি সমর্থন এবং সরবরাহ করার লক্ষ্যে পরিচালিত।

প্রতিটি। নেট অ্যাপ্লিকেশন, কনসোল অ্যাপ্লিকেশন ব্যতীত, নির্দিষ্ট অন্তর্নিহিত কাঠামোর উপর ভিত্তি করে এই শ্রেণীর একটি নির্দিষ্ট বাস্তবায়ন রয়েছে, যেমন: ডাব্লুপিএফ, উইন্ডোজফর্ম, অ্যাস্প নেট, সিলভারলাইট, ইসি ..

কোডটির অ্যাসক্রোনাস এক্সিকিউশন থেকে ফিরে আসা ফলাফল এবং সেই অসম্পূর্ণ কাজ থেকে ফলাফলের জন্য অপেক্ষা করা নির্ভরশীল কোডের কার্যকরকরণের মধ্যে ফলাফলের মধ্যে এই সামগ্রীর গুরুত্ব সিঙ্ক্রোনাইজেশনের সাথে আবদ্ধ।

এবং "প্রসঙ্গ" শব্দটি নির্বাহের প্রসঙ্গে বোঝায়, এটিই বর্তমান প্রয়োগের প্রেক্ষাপট যেখানে ওয়েটিং কোডটি কার্যকর করা হবে, যথা অ্যাসিঙ্ক কোড এবং এর ওয়েটিং কোডটির মধ্যে একটি সিঙ্ক্রোনাইজেশন বেটের একটি নির্দিষ্ট এক্সিকিউশন প্রসঙ্গে ঘটে, সুতরাং এই অবজেক্টটির নাম দেওয়া হয়েছে সিঙ্ক্রোনাইজেশন কনটেক্সট: এটি কার্যকর করা প্রসঙ্গে প্রতিনিধিত্ব করে যা অ্যাসিঙ্ক কোড এবং অপেক্ষার কোডের প্রয়োগের সিঙ্ক্রোনাইজেশন পরে দেখাবে


1

এই উদাহরণটি জোসেফ আলবাহারীর লিনকপ্যাডের উদাহরণ থেকে পাওয়া যায় তবে এটি সিঙ্ক্রোনাইজেশন প্রসঙ্গটি কী তা বুঝতে সাহায্য করে।

void WaitForTwoSecondsAsync (Action continuation)
{
    continuation.Dump();
    var syncContext = AsyncOperationManager.SynchronizationContext;
    new Timer (_ => syncContext.Post (o => continuation(), _)).Change (2000, -1);
}

void Main()
{
    Util.CreateSynchronizationContext();
    ("Waiting on thread " + Thread.CurrentThread.ManagedThreadId).Dump();
    for (int i = 0; i < 10; i++)
        WaitForTwoSecondsAsync (() => ("Done on thread " + Thread.CurrentThread.ManagedThreadId).Dump());
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.