ইভেন্ট হ্যান্ডলার মৃত্যুদণ্ড কার্যকর করার আদেশ


95

যদি আমি একাধিক ইভেন্ট হ্যান্ডলারগুলি সেট আপ করি তবে:

_webservice.RetrieveDataCompleted += ProcessData1;
_webservice.RetrieveDataCompleted += ProcessData2;

ইভেন্টটি RetrieveDataCompletedবরখাস্ত হওয়ার পরে হ্যান্ডলারের কী আদেশ হয় ? তারা কি একই থ্রেড এবং ক্রমান্বয়ে নিবন্ধিত ক্রমে চালানো হয়?


4
উত্তরটি retrieveDataCompleted ইভেন্টের জন্য সুনির্দিষ্ট হবে। যদি এটিতে কোনও মাল্টি-কাস্ট প্রতিনিধিদের ডিফল্ট ব্যাকিং স্টোর থাকে তবে হ্যাঁ "তারা একই থ্রেডে এবং ক্রমানুসারে নিবন্ধিত ক্রমে চালিত হয়"।
শুভনোমাদ

উত্তর:


134

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


6
আমি ভাবছি, ডাউনটাও কেন? এটি ঠিক সত্য, এবং সরাসরি প্রশ্নের উত্তর দেয় ...
রিড কোপসি

4
@ রোলিং: এটি বাইনারি অপারেটর ওভারলোড রেজোলিউশনের জন্য - ইভেন্ট হ্যান্ডলিংয়ের নয়। এই ক্ষেত্রে এটি অতিরিক্ত অপারেটর নয়।
রিড কোপসি

4
আহ, আমি কোথায় ভুল করছি তা দেখছি: "ইভেন্ট হ্যান্ডলাররা প্রতিনিধি, তাই না?" আমি এখন জানি তারা না। নিজেকে একটি ইভেন্ট লিখেছেন যা হ্যান্ডলারদের বিপরীত ক্রমে আগুন দেয়, কেবল নিজের কাছে এটি প্রমাণ করার জন্য :)
রাওলিং

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

6
ডাউনভোটেড যেহেতু এটি 2 পয়েন্টের পক্ষে সত্যই ভুল rect 1) বর্তমানে নির্দিষ্ট ক্রিয়াকলাপ বাস্তবায়নের আদেশ অনুসারে এগুলি কার্যকর করা হয় - যেহেতু আপনি ইভেন্টগুলির জন্য নিজের অ্যাড / অপসারণ পদ্ধতিগুলি প্রয়োগ করতে পারেন। 2) মাল্টি-কাস্ট প্রতিনিধিদের মাধ্যমে ডিফল্ট ইভেন্ট প্রয়োগটি ব্যবহার করার সময়, আদেশটি আসলে নির্দিষ্টকরণের দ্বারা প্রয়োজনীয়।
সেরেন বোইসেন

54

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

এখান থেকে: ডেলিগেট ক্লাস


4
দুর্দান্ত, তবে ইভেন্ট addএবং removeকীওয়ার্ডগুলি ব্যবহার করে অগত্যা মাল্টি-কাস্ট প্রতিনিধি হিসাবে প্রয়োগ করা হবে না।
শুভনোমাদ

ববসের মতোই , অন্যান্য উত্তরে উল্লেখ করা হয়েছে যে ইভেন্ট হ্যান্ডলারের সাথে এটির ব্যবহারটি এমন একটি বিষয় যা অবিশ্বাস্য হিসাবে গ্রহণ করা উচিত ... তা ঠিক কিনা বা না, এই উত্তরটিও সে সম্পর্কে কথা বলতে পারে।
n611x007

13

আপনি সমস্ত হ্যান্ডলারের বিচ্ছিন্ন করে ক্রম পরিবর্তন করতে পারেন এবং তারপরে পছন্দসই ক্রমে পুনরায় সংযুক্তি করতে পারেন।

public event EventHandler event1;

public void ChangeHandlersOrdering()
{
    if (event1 != null)
    {
        List<EventHandler> invocationList = event1.GetInvocationList()
                                                  .OfType<EventHandler>()
                                                  .ToList();

        foreach (var handler in invocationList)
        {
            event1 -= handler;
        }

        //Change ordering now, for example in reverese order as follows
        for (int i = invocationList.Count - 1; i >= 0; i--)
        {
            event1 += invocationList[i];
        }
    }
}

10

অর্ডারটি নির্বিচারে। আপনি কোনও বিশেষ ক্রমে একটি অনুরোধ থেকে পরের বারের জন্য মৃত্যুদন্ড কার্যকর করা হচ্ছে এমন উপর নির্ভর করতে পারবেন না।

সম্পাদনা করুন: এবং এছাড়াও - যদি না এটি কেবল কৌতূহলের বাইরে থাকে - আপনার জানা দরকার যে সত্যটি একটি গুরুতর নকশা সমস্যার সূচক।


4
অর্ডারটি নির্দিষ্ট ইভেন্টের প্রয়োগের উপর নির্ভর করে তবে এটি স্বেচ্ছাসেবী নয় । ইভেন্টের ডকুমেন্টেশনগুলি যদি অনুরোধ আদেশটি নির্দেশ না করে তবে আমি তাতে সম্মত হই যে এটি ঝুঁকিপূর্ণ। সেই শিরাতে আমি একটি ফলোআপ প্রশ্ন পোস্ট করেছি ।
শুভনোমাদ

9
একটি ইভেন্টের জন্য যা একটি পার্টিরিকুলার ক্রমে বিভিন্ন শ্রেণি দ্বারা পরিচালিত হওয়া দরকার তা আমার কাছে কোনও গুরুতর ডিজাইনের সমস্যা বলে মনে হয় না। সমস্যাটি ঘটবে যদি ইভেন্টের রেজিস্ট্রেশনগুলি এমনভাবে করা হয় যাতে অর্ডারটি গুরুত্বপূর্ণ বা গুরুত্বপূর্ণ তা জানতে অর্ড বা ইভেন্টটি জানতে অসুবিধা হয়।
ইগনাসিও সোলার গার্সিয়া

8

তারা নিবন্ধভুক্ত ক্রমে চালানো হয়। RetrieveDataCompletedএটি মাল্টিকাস্টের প্রতিনিধি । আমি চেষ্টা করে যাচাই করার জন্য প্রতিচ্ছবিটি সন্ধান করছি এবং দেখে মনে হচ্ছে সমস্ত কিছু ট্র্যাক রাখতে পর্দার আড়ালে কোনও অ্যারে ব্যবহার করা হয়েছে।


অন্যান্য উত্তরগুলি লক্ষ্য করে যে ইভেন্ট হ্যান্ডলারগুলির সাথে এটি 'দুর্ঘটনাজনক', 'ভঙ্গুর', 'বাস্তবায়নের বিশদ', ইত্যাদি ie কোনও মানক বা কনভেনশন দ্বারা প্রয়োজনীয় নয়, এটি কেবল ঘটে। এটা কি সঠিক? যে কোনও ক্ষেত্রে, এই উত্তরটিও এটি উল্লেখ করতে পারে।
n611x007

3

যদি কোনও সিস্টেম. উইন্ডোজ.ফর্মস.ফর্মের প্রসঙ্গে কারওটির এটির প্রয়োজন হয় তবে এখানে দেখানো ইভেন্টের ক্রমকে উল্টানো উদাহরণ is

using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace ConsoleApplication {
    class Program {
        static void Main() {
            Form form;

            form = createForm();
            form.ShowDialog();

            form = createForm();
            invertShownOrder(form);
            form.ShowDialog();
        }

        static Form createForm() {
            var form = new Form();
            form.Shown += (sender, args) => { Console.WriteLine("form_Shown1"); };
            form.Shown += (sender, args) => { Console.WriteLine("form_Shown2"); };
            return form;
        }

        static void invertShownOrder(Form form) {
            var events = typeof(Form)
                .GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic)
                .GetValue(form, null) as EventHandlerList;

            var shownEventKey = typeof(Form)
                .GetField("EVENT_SHOWN", BindingFlags.NonPublic | BindingFlags.Static)
                .GetValue(form);

            var shownEventHandler = events[shownEventKey] as EventHandler;

            if (shownEventHandler != null) {
                var invocationList = shownEventHandler
                    .GetInvocationList()
                    .OfType<EventHandler>()
                    .ToList();

                foreach (var handler in invocationList) {
                    events.RemoveHandler(shownEventKey, handler);
                }

                for (int i = invocationList.Count - 1; i >= 0; i--) {
                    events.AddHandler(shownEventKey, invocationList[i]);
                }
            }
        }
    }
}

2

একটি মাল্টিকাস্টডেলিগেটের প্রতিনিধিদের একটি লিঙ্কযুক্ত তালিকা রয়েছে, যাকে একটি বা একাধিক উপাদানের সমন্বয়ে আমন্ত্রণ তালিকা বলা হয়। যখন কোনও মাল্টিকাস্ট ডেলিগেট আহ্বান করা হয়, তখন নিমন্ত্রণ তালিকার প্রতিনিধিরা ক্রমক্রমে তাদের উপস্থিত হওয়ার সাথে সাথে ডাকা হয়। যদি তালিকাটি কার্যকর করার সময় ত্রুটি ঘটে থাকে তবে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হবে।


2

একটি অনুরোধের সময়, পদ্ধতিগুলি অনুরোধ তালিকায় প্রদর্শিত হয় সেই ক্রমে সেগুলি চাওয়া হয়।

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


1

এটি এমন একটি ফাংশন যা আপনি যেখানে মাল্টিডিলেট আমন্ত্রণ তালিকার তালিকায় চান সেখানে নতুন ইভেন্ট হ্যান্ডলার ফাংশনটি রাখবে।

    private void addDelegateAt(ref YourDelegate initial, YourDelegate newHandler, int position)
    {
        Delegate[] subscribers = initial.GetInvocationList();
        Delegate[] newSubscriptions = new Delegate[subscribers.Length + 1];

        for (int i = 0; i < newSubscriptions.Length; i++)
        {
            if (i < position)
                newSubscriptions[i] = subscribers[i];
            else if (i==position)
                newSubscriptions[i] = (YourDelegate)newHandler;
            else if (i > position)
                newSubscriptions[i] = subscribers[i-1];
        }

        initial = (YourDelegate)Delegate.Combine(newSubscriptions);
    }

তারপরে আপনি আপনার কোডটি যেখানেই সুবিধাজনক যেখানেই '- =' দিয়ে ফাংশনটি সরাতে পারেন।

পিএস - আমি 'পজিশন' প্যারামিটারের জন্য কোনও ত্রুটি পরিচালনা করছি না।


0

আমারও একই সমস্যা ছিল। আমার ক্ষেত্রে এটি খুব সহজেই ঠিক করা হয়েছিল। আমি এমন প্রতিনিধি কখনও দেখিনি যা + + অপারেটর ব্যবহার করে না। আমার প্রতিনিয়ত সবসময় শেষে একজন প্রতিনিধি যুক্ত হওয়ার দ্বারা সমাধান করা হয়েছিল, অন্য সমস্তটি শুরুতে সর্বদা যুক্ত করা হয়। ওপির উদাহরণটি এমন হবে:

    _webservice.RetrieveDataCompleted = _webservice.RetrieveDataCompleted + ProcessData1;
    _webservice.RetrieveDataCompleted = ProcessData2 + _webservice.RetrieveDataCompleted;

প্রথম ক্ষেত্রে প্রসেসডাটা 1 সর্বশেষ বলা হবে। ২ য় ক্ষেত্রে প্রসেসডাটা 2 কে প্রথমে ডাকা হবে।

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