সি # ইভেন্টগুলি কি সিনক্রোনাস?


104

এই প্রশ্নের দুটি অংশ রয়েছে:

  1. না উত্থাপন একটি ইভেন্ট থ্রেড ব্লক, অথবা এটি EventHandlers সঞ্চালনের দ্বারা অ্যাসিঙ্ক্রোনাস এর শুরু এবং থ্রেড যায় একই সময়ে চলতে?

  2. হয় পৃথক EventHandlers (ইভেন্টে সদস্যতা নেওয়া) সিঙ্ক্রোনাস একের পর এক চালান, বা তারা কোন গ্যারান্টি যা অন্যদের একই সময়ে চলমান না হয় অ্যাসিঙ্ক্রোনাস চালানো হয়?

উত্তর:


37

আপনার প্রশ্নের উত্তর দিতে:

  1. ইভেন্ট হ্যান্ডলারগুলি সমস্ত সিঙ্ক্রোনালি প্রয়োগ করা থাকলে কোনও ইভেন্ট উত্থাপন থ্রেডকে আটকে দেয়।
  2. ইভেন্ট হ্যান্ডলারগুলি ক্রমানুসারে একের পর এক মৃত্যুদন্ড কার্যকর করা হয় যাতে তারা ইভেন্টটিতে সাবস্ক্রাইব হয়।

আমিও অভ্যন্তরীণ প্রক্রিয়া eventএবং এর সম্পর্কিত ক্রিয়াকলাপ সম্পর্কে আগ্রহী ছিলাম was তাই আমি একটি সাধারণ প্রোগ্রাম লিখেছিলাম এবং ildasmএর বাস্তবায়নটি ঘিরে ধরেছিলাম।

সংক্ষিপ্ত উত্তরটি হ'ল

  • ইভেন্টগুলি সাবস্ক্রাইব করতে বা আহ্বান জানাতে কোনও অ্যাসিক্রোনাস অপারেশন জড়িত নেই।
  • ইভেন্টটি একই প্রতিনিধি প্রকারের একটি সমর্থনকারী প্রতিনিধি ক্ষেত্রের সাথে প্রয়োগ করা হয়
  • সাবস্ক্রাইব করা হয় Delegate.Combine()
  • এর সাথে সাবস্ক্রাইব করা হয় Delegate.Remove()
  • আমন্ত্রণটি কেবল চূড়ান্ত সম্মিলিত প্রতিনিধিকে অনুরোধ করেই করা হয়

আমি যা করেছি তা এখানে। আমি যে প্রোগ্রামটি ব্যবহার করেছি:

public class Foo
{
    // cool, it can return a value! which value it returns if there're multiple 
    // subscribers? answer (by trying): the last subscriber.
    public event Func<int, string> OnCall;
    private int val = 1;

    public void Do()
    {
        if (OnCall != null) 
        {
            var res = OnCall(val++);
            Console.WriteLine($"publisher got back a {res}");
        }
    }
}

public class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();

        foo.OnCall += i =>
        {
            Console.WriteLine($"sub2: I've got a {i}");
            return "sub2";
        };

        foo.OnCall += i =>
        {
            Console.WriteLine($"sub1: I've got a {i}");
            return "sub1";
        };

        foo.Do();
        foo.Do();
    }
}

এখানে ফু এর বাস্তবায়ন:

এখানে চিত্র বর্ণনা লিখুন

মনে রাখবেন একটি ক্ষেত্র OnCall এবং একটি ইভেন্ট রয়েছে OnCall । ক্ষেত্রটি OnCallঅবশ্যই সমর্থনযোগ্য সম্পত্তি। এবং এটি নিছক একটি Func<int, string>, এখানে অভিনব কিছুই।

আকর্ষণীয় অংশগুলি হ'ল:

  • add_OnCall(Func<int, string>)
  • remove_OnCall(Func<int, string>)
  • এবং কীভাবে OnCallআমন্ত্রিত হয়Do()

সাবস্ক্রাইব এবং আনসাবস্ক্রাইবিং কীভাবে কার্যকর করা হয়?

এখানে add_OnCallসিআইএল এর সংক্ষিপ্ত বাস্তবায়ন। মজার অংশটি হ'ল এটি Delegate.Combineদুটি প্রতিনিধিদের সম্মতি জানাতে ব্যবহার করে।

.method public hidebysig specialname instance void 
        add_OnCall(class [mscorlib]System.Func`2<int32,string> 'value') cil managed
{
  // ...
  .locals init (class [mscorlib]System.Func`2<int32,string> V_0,
           class [mscorlib]System.Func`2<int32,string> V_1,
           class [mscorlib]System.Func`2<int32,string> V_2)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class [mscorlib]System.Func`2<int32,string> ConsoleApp1.Foo::OnCall
  // ...
  IL_000b:  call       class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
                                                                                          class [mscorlib]System.Delegate)
  // ...
} // end of method Foo::add_OnCall

তেমনি, Delegate.Removeব্যবহৃত হয় remove_OnCall

কীভাবে একটি ইভেন্ট ডাকা হয়?

প্রার্থনা করার OnCallজন্য Do(), এটি কেবল আর্গটি লোড করার পরে চূড়ান্ত সংক্ষিপ্ত প্রতিনিধিকে কল করে:

IL_0026:  callvirt   instance !1 class [mscorlib]System.Func`2<int32,string>::Invoke(!0)

একজন গ্রাহক একটি ইভেন্টে ঠিক কীভাবে সাবস্ক্রাইব করেন?

এবং অবশেষে, Mainআশ্চর্যের সাথে নয়, OnCallইভেন্টটির সাবস্ক্রাইব add_OnCallকরে Fooউদাহরণটি কল করার পদ্ধতিটি করা হয় ।


3
সাবাশ!! আমি এই প্রশ্নটি জিজ্ঞাসা করে অনেক দীর্ঘ হয়েছে। আপনি যদি শীর্ষে অক্ষর রাখতে পারেন যা সরাসরি আমার দুই অংশের প্রশ্নের উত্তর দেয় (যেমন, "# 1 উত্তর হ'ল না; # 2 উত্তর হ'ল না") তবে আমি এটির সরকারী উত্তর করব। আমি আমার পোস্টটিকে আমার মূল প্রশ্নের উত্তর দেওয়ার জন্য সমস্ত টুকরো হিসাবে বাজি দিচ্ছি, তবে যেহেতু আমি আর সি # ব্যবহার করি না (এবং অন্যান্য গুগলরা এই ধারণাগুলিতে নতুন হতে পারে) সে কারণেই আমি মৌখিক কথা বলছি যা উত্তরগুলি স্পষ্ট করে দেয়।
আলেকজান্ডার বার্ড

ধন্যবাদ @ আলেকজান্ডারবার্ড, উত্তরগুলি শীর্ষে রাখার জন্য এটি সম্পাদনা করেছেন।
কেএফএল

@ কেএফএল, এটি এখনও অস্পষ্ট, আমি অ্যালেক্সের মত একই মন্তব্য করতে চলেছিলাম। একটি সরল "হ্যাঁ, তারা সংক্রামক", সহায়ক হবে
জননি 5

71

এটি একটি সাধারণ উত্তর এবং ডিফল্ট আচরণ প্রতিফলিত করে:

  1. হ্যাঁ, এটি থ্রেডটিকে অবরুদ্ধ করে, যদি ইভেন্টটির সদস্যতা প্রাপ্ত পদ্ধতিগুলি অ্যাসিঙ্ক্রোনাস না হয়।
  2. একের পর এক মৃত্যুদণ্ড কার্যকর করা হয় তাদের। এটিতে আরও একটি টুইস্ট রয়েছে: যদি কোনও ইভেন্ট হ্যান্ডলার কোনও ব্যতিক্রম ছুঁড়ে ফেলে তবে ইভেন্ট হ্যান্ডলারগুলি কার্যকর করা হয় নি।

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

[দ্রষ্টব্য] এই লিঙ্কটির ইভেন্টস হেল্পার ক্লাসটি ডাউনলোড করার জন্য আপনাকে একটি ইমেল ঠিকানা সরবরাহ করা প্রয়োজন। (আমি কোনওভাবেই অনুমোদিত নয়)


আমি কয়েকটি ফোরামের পোস্ট পড়েছি, যা থেকে দুজন যথাযথ কারণ প্রদান না করে প্রথম পয়েন্টটির বিরোধিতা করেছে। আমি আপনার উত্তরটি নিয়ে সন্দেহ করি না, (এটি আমি এখনও অবধি যা अनुभव করেছি তার সাথে মেলে) প্রথম পয়েন্টে কোনও অফিসিয়াল ডকুমেন্টেশন আছে কি? আমার এ সম্পর্কে নিশ্চিত হওয়া দরকার, তবে এই সঠিক বিষয়ে কোনও কর্মকর্তা খুঁজে পেতে আমার অসুবিধা রয়েছে।
আদম এলএস

@ AdamL.S। ঘটনাটি কীভাবে বলা হয় এটি একটি বিষয়। সুতরাং এটি ইভেন্ট সরবরাহ করে এমন শ্রেণীর উপর নির্ভর করে।
ড্যানিয়েল হিলগারথ

14

ইভেন্টটিতে সাবস্ক্রাইব করা প্রতিনিধিরা ক্রমে যুক্ত হওয়ার সাথে ক্রমে অনুরোধ করা হয়েছিল। যদি প্রতিনিধিদের মধ্যে কেউ ব্যতিক্রম ছুঁড়ে ফেলে, তবে নিম্নলিখিত ব্যক্তিদের ডাকা হবে না

যেহেতু ইভেন্টগুলি মাল্টিকাস্ট প্রতিনিধিদের সাথে সংজ্ঞায়িত করা হয়েছে, তাই আপনি নিজের ফায়ারিং মেকানিজম ব্যবহার করে লিখতে পারেন

Delegate.GetInvocationList();

এবং প্রতিনিধিদের অবিচ্ছিন্নভাবে অনুরোধ করা;


12

ইভেন্টগুলি কেবল প্রতিনিধিদের অ্যারে হয়। যতক্ষণ ডেলিগেট কল সমকালীন হয় ততক্ষণ ইভেন্টগুলিও সমকালীন।


7

সাধারণভাবে, ইভেন্টগুলি সিনক্রোনাস হয়। তবে কিছু ব্যতিক্রম রয়েছে, যেমন নਾਲ হলে System.Timers.Timer.Elapsedকোনও ThreadPoolথ্রেডে উত্থাপিত ইভেন্ট SyncronisingObject

দস্তাবেজ: http://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed.aspx


3

সি # তে ইভেন্টগুলি সমকালীনভাবে চালিত হয় (উভয় ক্ষেত্রেই), যতক্ষণ না আপনি ম্যানুয়ালি দ্বিতীয় থ্রেড শুরু করেন না।


আমি একটি অ্যাসিঙ্ক ইভেন্ট হ্যান্ডলারটি কী করব? এটি কি তখন অন্য থ্রেডে চলবে? আমি "সমস্তভাবে অ্যাসিঙ্ক" সম্পর্কে শুনেছি, তবে মনে হচ্ছে অ্যাসিঙ্ক ইভেন্ট হ্যান্ডলারদের নিজস্ব থ্রেড রয়েছে? আমি বুঝতে পারি না: / আপনি কি আমাকে আলোকিত করতে পারেন?
উইঙ্গার সেন্ডন

3

ইভেন্টগুলি সিঙ্ক্রোনাস হয়। এই কারণেই ইভেন্ট লাইফসাইকেলটি এটির মতো কাজ করে। ইনটগুলি লোড হওয়ার আগে ঘটে, রেন্ডারগুলির আগে লোড ঘটে ইত্যাদি ইত্যাদি

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

এমনকি অ্যাসিনক্রোনাস কলগুলি একটি ডিগ্রির সাথে সিঙ্ক্রোনাস। শুরুটি শেষ হওয়ার আগে শেষটি বলা অসম্ভব।

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