দাওয়াত (প্রতিনিধি)


93

কেউ দয়া করে এই লিঙ্কে লিখিত এই বিবৃতি ব্যাখ্যা করতে পারেন

Invoke(Delegate):

নিয়ন্ত্রণের অন্তর্নিহিত উইন্ডো হ্যান্ডেলের মালিক থ্রেডে নির্দিষ্ট প্রতিনিধিটিকে কার্যকর করে

এর অর্থ কী (কেউ বিশেষত সাহসী) আমি কী তা ব্যাখ্যা করতে পারি তা আমি পরিষ্কারভাবে জানতে পারছি না


4
এই প্রশ্নের উত্তর Control.InvokeRequired সম্পত্তি আবদ্ধ থাকে - দেখুন msdn.microsoft.com/en-us/library/...
ড্যাশ

উত্তর:


131

এই প্রশ্নের উত্তর সি # নিয়ন্ত্রণগুলি কীভাবে কাজ করে তার মধ্যে রয়েছে

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

থেকে Control.InvokeRequired

কার্যকরভাবে, ইনভোক যা করে তা নিশ্চিত করে যে আপনি যে কোডটি কল করছেন সেটি সেই থ্রেডে ঘটে যা নিয়ন্ত্রণ "ক্রমে চালিত" ক্রস থ্রেডযুক্ত ব্যতিক্রমগুলি কার্যকরভাবে রোধ করে।

Historicalতিহাসিক দৃষ্টিকোণ থেকে,। নেট 1.1 এ, এটি আসলে অনুমোদিত হয়েছিল। এর অর্থ হ'ল আপনি যে কোনও ব্যাকগ্রাউন্ড থ্রেড থেকে "জিইউআই" থ্রেডে কোডটি চেষ্টা করতে এবং সম্পাদন করতে পারেন এবং এটি বেশিরভাগ ক্ষেত্রেই কাজ করবে। কখনও কখনও এটি আপনার অ্যাপ্লিকেশনটি প্রস্থান করতে পারে কারণ আপনি অন্যভাবে কিছু করার সময় আপনি জিইউআই থ্রেডকে কার্যকরভাবে বাধা দিয়েছিলেন। এটি ক্রস থ্রেডেড ব্যতিক্রম - জিইআইআই অন্য কোনও চিত্র আঁকছে এমন সময় কোনও পাঠ্যবক্স আপডেট করার চেষ্টা করার কথা ভাবুন।

  • কোন পদক্ষেপটি অগ্রাধিকার নেয়?
  • দুজনের পক্ষে একবারে ঘটানোও কি সম্ভব?
  • জিইউআই চালানোর জন্য প্রয়োজনীয় অন্যান্য কমান্ডগুলির কী ঘটে?

কার্যকরভাবে, আপনি একটি কাতারে বাধা দিচ্ছেন, যার প্রচুর অপ্রত্যাশিত পরিণতি হতে পারে। আপনি যে কাতারে যা করতে চান তা পাওয়ার জন্য ইনভোকটি কার্যকরভাবে "ভদ্র" উপায় এবং এই নিয়মটি .NET 2.0 থেকে নিক্ষিপ্ত অবৈধ অপেশনের মাধ্যমে প্রবর্তন করা হয়েছিল

পর্দার আড়ালে আসলে কী চলছে এবং "জিইউআই থ্রেড" বলতে কী বোঝায় তা বোঝার জন্য একটি মেসেজ পাম্প বা বার্তা লুপটি কী তা বোঝা দরকারী।

" মেসেজ পাম্প কী কী " প্রশ্নটিতে এটি ইতিমধ্যে উত্তর পেয়েছে নিয়ন্ত্রণের সাথে ইন্টারঅ্যাক্ট করার সময় আপনি যে প্রকৃত প্রক্রিয়াটি বেঁধে দিচ্ছেন তা বোঝার জন্য এটি পড়ার পরামর্শ দেওয়া হচ্ছে।

আপনি যে দরকারী পড়তে পারেন সেগুলি পড়ার মধ্যে রয়েছে:

বিগন ইনভোকের সাথে কী হচ্ছে

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

এবং, একটি প্রতিনিধি নমুনা সহ আরও কোড ভারী ওভারভিউয়ের জন্য:

অবৈধ ক্রস-থ্রেড অপারেশন

// the canonical form (C# consumer)

public delegate void ControlStringConsumer(Control control, string text);  // defines a delegate type

public void SetText(Control control, string text) {
    if (control.InvokeRequired) {
        control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text});  // invoking itself
    } else {
        control.Text=text;      // the "functional part", executing only on the main thread
    }
}

একবার ইনভোকেরওয়েয়ার্ডের জন্য আপনার প্রশংসা হয়ে গেলে, আপনি এই কলগুলি মোড়ানোর জন্য কোনও এক্সটেনশন পদ্ধতিটি ব্যবহার করার কথা ভাবতে চাইতে পারেন। এটি স্ট্যাক ওভারফ্লো প্রশ্নটি ক্লোভিং কোড কোড ইনভোকের সাথে প্রয়োজনীয় লিটারে আবৃত ।

Historতিহাসিকভাবে যা ঘটেছিল তা আগ্রহের বিষয় হতে পারে সে সম্পর্কে আরও একটি লেখা রয়েছে


71

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

উদাহরণস্বরূপ, আপনি যদি কোনও শ্রমিক থ্রেড থেকে কোনও লেবেলের পাঠ্য পরিবর্তন করতে চান তবে আপনি এই জাতীয় কিছু করতে পারেন:

theLabel.Invoke(new Action(() => theLabel.Text = "hello world from worker thread!"));

কেউ ব্যাখ্যা করতে পারেন কেন কেউ এমন কিছু করবে? this.Invoke(() => this.Enabled = true);যা thisবোঝায় তা অবশ্যই বর্তমান থ্রেডে আছে, তাই না?
কাইল ডেলাানি 19

4
@ কাইলডিলেনি, কোনও বস্তু থ্রেডে "ইন" নেই এবং বর্তমান থ্রেডটি অবশ্যই থ্রেড নয় যা এই বস্তুটি তৈরি করেছে।
থমাস লেভেস্ক

24

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

নীচে নমুনা থ্রেড 1 একটি ব্যতিক্রম ছুঁড়েছে কারণ সেটটেক্সট 1 অন্য থ্রেড থেকে পাঠ্যবক্স 1 পরিবর্তন করতে চেষ্টা করছে। তবে থ্রেড 2-এ, টেক্সটবক্স তৈরি হওয়া থ্রেডে অ্যাকশন ইন সেটটেক্সট 2 কার্যকর করা হয়

private void btn_Click(object sender, EvenetArgs e)
{
    var thread1 = new Thread(SetText1);
    var thread2 = new Thread(SetText2);
    thread1.Start();
    thread2.Start();
}

private void SetText1() 
{
    textBox1.Text = "Test";
}

private void SetText2() 
{
    textBox1.Invoke(new Action(() => textBox1.Text = "Test"));
}

আমি সত্যিই এই পদ্ধতির পছন্দ করি, এটি প্রকৃতির প্রতিনিধিদের আড়াল করে, তবে যাইহোক এটি দুর্দান্ত শর্টকাট।
shytikov

8
Invoke((MethodInvoker)delegate{ textBox1.Text = "Test"; });

সিস্টেমের ব্যবহার.অ্যাকশন লোকেরা অন্যান্য প্রতিক্রিয়াগুলিতে পরামর্শ দেয় কেবল পুরানো সংস্করণগুলির জন্য 3.5+ ফ্রেমওয়ার্কে কাজ করে, এটি পুরোপুরি কাজ করে
সুইসাইড প্লাটিপাস

2

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

প্যাটার্নটি হ'ল:

void OnEvent(object sender, EventArgs e)
{
   if (this.InvokeRequired)
   {
       this.Invoke(() => this.OnEvent(sender, e);
       return;
   }

   // do stuff (now you know you are on the main thread)
}

2

this.Invoke(delegate)নিশ্চিত করুন যে আপনি প্রতিনিধিটিকে this.Invoke()মূল থ্রেড / তৈরি থ্রেডে কল করছেন।

আমি বলতে পারি একটি থাম্ব নিয়ম প্রধান থ্রেড বাদে আপনার ফর্ম নিয়ন্ত্রণগুলিতে অ্যাক্সেস করে না।

ইনভোক () ব্যবহারের জন্য নিম্নলিখিত লাইনগুলি বোধগম্য হতে পারে

    private void SetText(string text)
    {
        // InvokeRequired required compares the thread ID of the
        // calling thread to the thread ID of the creating thread.
        // If these threads are different, it returns true.
        if (this.textBox1.InvokeRequired)
        {   
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textBox1.Text = text;
        }
    }

এমন পরিস্থিতিতে রয়েছে যদিও আপনি একটি থ্রেডপুল থ্রেড তৈরি করেন (অর্থাত্ কর্মী থ্রেড) এটি মূল থ্রেডে চলবে। এটি কোনও নতুন থ্রেড তৈরি করবে না কোজ মূল থ্রেড আরও নির্দেশাবলী প্রক্রিয়াকরণের জন্য উপলব্ধ। সুতরাং প্রথমে চলমান চলমান থ্রেডটি মূল থ্রেড ব্যবহার করে কিনা তা অনুসন্ধান করুন this.InvokeRequiredযদি সত্য হয় যে বর্তমান কোডটি কর্মী থ্রেডে চলছে কিনা তাই এটিকে কল করুন n আহ্বান করুন (ডি, নতুন অবজেক্ট [] {পাঠ্য});

অন্যথায় সরাসরি ইউআই নিয়ন্ত্রণ আপডেট করুন (এখানে আপনি গ্যারান্টিযুক্ত যে আপনি কোডটি মূল থ্রেডে চালাচ্ছেন))


1

এর অর্থ হ'ল প্রতিনিধিটি ইউআই থ্রেডে চলবে, আপনি যদি কোনও পটভূমি কর্মী বা থ্রেড-পুল থ্রেড থেকে সেই পদ্ধতিটি কল করেনও। ইউআই উপাদানগুলির থ্রেডের সখ্যতা রয়েছে - তারা কেবল একটি থ্রেডের সাথে সরাসরি কথা বলতে পছন্দ করে: ইউআই থ্রেড। ইউআই থ্রেডটি এমন থ্রেড হিসাবে সংজ্ঞায়িত করা হয়েছে যা নিয়ন্ত্রণের উদাহরণ তৈরি করেছে এবং তাই উইন্ডো হ্যান্ডেলের সাথে যুক্ত with তবে এগুলি সবই একটি বাস্তবায়নের বিশদ।

মূল বিষয়টি হ'ল: আপনি এই পদ্ধতিটি কোনও কর্মী থ্রেড থেকে কল করবেন যাতে আপনি ইউআই অ্যাক্সেস করতে পারেন (লেবেলের মান পরিবর্তন করতে পারেন ইত্যাদি) - যেহেতু আপনাকে ইউআই থ্রেডের চেয়ে অন্য কোনও থ্রেড থেকে এটি করার অনুমতি দেওয়া হচ্ছে না।


0

প্রতিনিধি মূলত ইনলাইন Actionএর বা Func<T>। আপনি যে পদ্ধতিটি চালাচ্ছেন বা একটি lambdaএক্সপ্রেশন ব্যবহার করছেন তার পদ্ধতির বাইরে আপনি কোনও প্রতিনিধি ঘোষণা করতে পারেন ( =>); যেহেতু আপনি কোনও পদ্ধতির মধ্যে প্রতিনিধিটি চালান, আপনি এটি থ্রেডে চালান যা বর্তমান উইন্ডো / অ্যাপ্লিকেশনটির জন্য চালিত হচ্ছে যা কিছুটা সাহসী।

লাম্বদা উদাহরণ

int AddFiveToNumber(int number)
{
  var d = (int i => i + 5);
  d.Invoke(number);
}

0

এর অর্থ হ'ল আপনি যে প্রতিনিধিটি পাস করেছেন তা থ্রেডে কার্যকর করা হয়েছে যা কন্ট্রোল অবজেক্ট তৈরি করেছে (যা ইউআই থ্রেড)।

আপনার অ্যাপ্লিকেশনটি বহু-থ্রেডযুক্ত হওয়ার সময় আপনাকে এই পদ্ধতিটি কল করতে হবে এবং আপনি ইউআই থ্রেড ব্যতীত অন্য কোনও থ্রেড থেকে কিছু ইউআই অপারেশন করতে চান, কারণ আপনি যদি কেবল অন্য থ্রেড থেকে একটি নিয়ন্ত্রণের কোনও পদ্ধতিতে কল করার চেষ্টা করেন তবে আপনি এটি পাবেন System.In अवैधOperationException।

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