Bir olay dinleyicisi nasıl çalışır?


125

Bugün Birlik hakkındaki derslerimden birinde, kullanıcının bir düğmeye bastığında her kareyi kontrol ederek oyuncu konumumuzu güncellemeyi tartıştık. Birisi bunun verimsiz olduğunu ve bunun yerine olay dinleyicisini kullanmamız gerektiğini söyledi.

Sorum şu ki, programlama dili veya uygulandığı durum ne olursa olsun, bir olay dinleyicisi nasıl çalışır?

Sezgim, olay dinleyicisinin olayın başlatılıp başlatılmadığını sürekli olarak kontrol ettiğini, yani senaryomda, olayın başlatıldığı her kareyi kontrol etmekten farklı olmayacağını varsayıyordu.

Sınıftaki tartışmaya dayanarak, olay dinleyicisinin farklı şekilde çalıştığı görülmektedir.

Bir olay dinleyicisi nasıl çalışır?


34
Bir olay dinleyicisi hiç kontrol etmez. Olay "ateşi" dinlerken olduğu zaman çağrılıyor.
Robert Harvey,

13
Evet, ama nasıl "dinler", sürekli kontrol etmez mi?
Gary Holiday

28
Hayır! "Etkinlik Dinleyicisi" muhtemelen kötü bir sözcük seçimidir; aslında hiç "dinlemiyor". Bir olay dinleyicisinin yaptığı tüm olay, diğer yöntemlere benzer şekilde, ateşlendiğinde olayın çağrılmasını beklemektir. Bu şekilde çağrılana kadar hiçbir şey yapmaz.
Robert Harvey,

28
Düğmeye basılıp basılmadığını görmek her kontrol ettiğinizde saat döngüleri size mal olur. Olay işleyicisi (dinleyici) yalnızca düğmeye gerçekten basıldığında size masraf getirir.
Robert Harvey,

45
@RobertHarvey - "dinleyicilerin" hala daha düşük seviyede sürekli oylamaya ihtiyacı olduğu için mutlaka değil. Karmaşıklığı sadece kendi derinlikteki kod katmanınızdan donanım kesintilerine ya da her neye zorlarsınız. Ve evet, bu genellikle daha verimli olur, ancak dinleme, yoklamadan daha üstün olduğu için değil, düşük seviyede yoklama, siz ve donanım arasındaki soyutlama C # ve 15 katlarından yoklamadan daha verimli olduğu için olmaz.
Davor Ždralo,

Yanıtlar:


140

Sağladığınız yoklama örneğinin aksine (düğmenin her karede işaretlendiği yer), bir olay dinleyicisi düğmeye basılıp basılmadığını kontrol etmez. Bunun yerine, düğmeye basıldığında çağrılır.

Belki de "olay dinleyicisi" terimi sizi atıyordur. Bu terim, “dinleyicinin” aktif olarak dinleyecek bir şey yaptığını, aslında hiçbir şey yapmadığını gösteriyor. "Dinleyici", yalnızca etkinliğe abone olan bir işlev veya yöntemdir. Olay patladığında, dinleyici yöntemi ("olay işleyici") çağrılır.

Olay düzeninin yararı, düğmeye gerçekten basılıncaya kadar herhangi bir maliyet olmamasıdır. Olay, bu şekilde izlenebilir, çünkü "donanım kesintisi" dediğimiz şeyden kaynaklanır, bu da olayın başlatılması için kodun kısa bir süre kullanılmasını önler.

Bazı kullanıcı arabirimi ve oyun çerçeveleri, daha sonra (genellikle kısa) bir süre içinde olayları yürütmek için sıraya koyan "mesaj döngüsü" olarak adlandırılan bir şey kullanır, ancak yine de bu olayı ilk önce mesaj döngüsüne almak için bir donanım kesintisine ihtiyacınız vardır.


54
Düğmeye basılıncaya kadar hiçbir maliyet olmama sebebinin, düğmelerin "özel" olması, bilgisayarın kesintiye uğraması ve işletim sisteminin kullanabileceği, kullanıcı alanı uygulamalarına göre soyutlanmış diğer özel olanakları olduğu için bahsetmeye değer olabilir.
whatsisname,

46
@whatsisname bu durumda iken çok derin oyun motorları kesintilerini çalışmıyor muhtemeldir, ama yine de aslında bir döngü içinde bir olay kaynağı yoklama olan uygulamada kaputun altında. Daha olay dinleyicileri ekleyerek eklemek kalmaması bu yoklama, merkezi ve optimize edilmiş bu sadece var ek yoklama ve karmaşıklığını.
gntskn

7
@ PieterGeerkens, gntskn'ın oyun motoru döngüsünün bir parçası olarak, bekleyen tüm olayları kontrol eden bir adım olduğu anlamına geldiğini tahmin ediyorum. Olaylar her döngü sırasında döngü başına diğer tüm etkinliklerle birlikte işlenir. Olayları kontrol etmek için ayrı bir döngü olmazdı .
Joshua Taylor,

2
@Voo: Bu yazıda bu ayrıntı düzeyine girmemek için tüm sebepler.
Robert Harvey,

2
@Voo: Klavyedeki fiziksel tuşlar ve fare düğmelerindeki düğmelerden bahsediyorum.
whatsisname,

52

Bir e-posta bülteni aboneliğine benzer bir olay dinleyicisi (bir web sayfasını sonsuz bir şekilde yenilemek yerine (bilgi aktarımını başlatanı olduğunuz)) bir e-posta bültenine abone olun.

Abone listesini yöneten olay nesneleri kullanılarak bir olay sistemi uygulanır. İlgilenilen nesneler ( aboneler , dinleyiciler , delegeler vb.), Etkinlik listesine kendilerini ekleyen ve etkinlik listesine kendilerini ekleyen bir yöntem çağırarak, etkinlik hakkında bilgi sahibi olmak için abone olabilirler. Olay Ne zaman ateş (terminoloji de içerebilir: denilen , tetikleyen , çağrılan , koşmak , vb) onlar anlamamız gerekir içeriksel türlü bilgi boyunca geçen olayın onları bilgilendirmek için, bu abonelerin her biri üzerinde uygun yöntemi çağırır ne oldu.


38

Kısa, tatmin edici cevap, başvurunun bir sinyal (olay) alması ve rutinin sadece bu noktada çağrılmasıdır.

Uzun açıklama biraz daha ilgili.

Müşteri etkinlikleri nereden geliyor?

Her modern uygulama , olayları onları alması gereken doğru bileşenlere gönderen, genellikle yarı gizli bir "olay döngüsüne" sahiptir. Örneğin, geçerli fare koordinatlarında yüzeyi görünen düğmeye bir "click" olayı gönderilir. Bu en basit seviyededir. Gerçekte, işletim sistemi bu olayların çoğunu yapar, çünkü bazı olaylar ve bazı bileşenler doğrudan mesaj alır.

Uygulama etkinlikleri nereden geliyor?

İşletim sistemleri olayları olduğu gibi gönderir. Bunu kendi sürücüleri tarafından bilgilendirilerek reaktif olarak yaparlar.

Sürücüler nasıl etkinlik oluşturur?

Uzman değilim, ancak kesin kullanım CPU kesiliyor: Yeni veriler mevcut olduğunda kontrol ettikleri donanım CPU üzerindeki bir pimi yükseltir; CPU, sonunda gönderilecek bir (sıra) olayı oluşturan gelen verileri yöneten sürücüyü çalıştırır ve ardından kontrolü OS'ye geri döndürür.

Gördüğünüz gibi, uygulamanız her zaman gerçekten çalışmıyor. Olaylar gerçekleştikçe OS (sorta) tarafından kovulan bir grup prosedür var, ancak zamanın geri kalanında hiçbir şey yapmıyor.


farkedilmeyen istisnalar vardır, örneğin, bir kez için farklı şeyler yapabilecek oyunlar


10
Bu cevap, bir tarayıcıda fare tıklaması olayları için neden bir yoklama olmadığını açıklar. Donanım, interrupt üretir => sürücü, onu OS olayına, => tarayıcı, bunu DOM olayına çözer:> JS motoru, o olay için dinleyiciyi çalıştırır.
Tibos

@Tibos da klavye olayları, zamanlayıcı olayları, boya olayları, vb. İçin de geçerlidir.
Sklivvz

19

terminoloji

  • olay : Olabilecek bir şey türü.

  • olay ateşleme : Bir olayın belirli bir oluşumu; gerçekleşen bir olay.

  • Etkinlik dinleyicisi : Etkinlik ateşlemelerine bakan bir şey.

  • olay işleyicisi : Bir olay dinleyicisi bir olayın ateşlendiğini tespit ettiğinde meydana gelen bir şey.

  • olay abonesi : Etkinlik işleyicisinin araması gereken bir yanıt.

Bu tanımlar uygulamaya bağlı değildir, bu nedenle farklı şekillerde uygulanabilirler.

Bu terimlerden bazıları genellikle eşanlamlılar için yanlıştır, çünkü kullanıcıların aralarında ayrım yapmalarına gerek yoktur.

Ortak senaryolar

  1. Programlama-mantık olayları.

    • Olay bazı yöntem çağrılır ne zaman olacağı.

    • Bir olay ateşleme , bu yönteme yapılan özel bir çağrıdır.

    • Olay dinleyicisi olay işleyicisi çağıran her olay ateş üzerinde deniyor olay yönteminde bir kanca.

    • Olay işleyicisi olay abonelerin bir koleksiyon çağırır.

    • Olay abone (ler) gerçekleştirmek türlü tedbiri (ler) sistem olayın oluşumu cevaben gerçekleşmesi demektir.

  2. Harici etkinlikler.

    • Olay gözlenebilirlerinin anlaşılabilir bir dış oluyor.

    • Bir olayın ateşlenmesi , harici bir olayın gerçekleştiği olarak algılanabildiği zamandır.

    • Olay dinleyicisi bir şekilde sık sık yoklama tarafından, olay işten çıkarmaları algılar gözlemlenebilir (ler), ardından ateş bir olay tespit ettiğinde olay işleyicisi çağırır.

    • Olay işleyicisi olay abonelerin bir koleksiyon çağırır.

    • Olay abone (ler) gerçekleştirmek türlü tedbiri (ler) sistem olayın oluşumu cevaben gerçekleşmesi demektir.

Yoklama - olayın ateşleme mekanizmasına kanca takma

Başkaları tarafından yapılan mesele, oy kullanma sık sık gerekli değildir. Bunun nedeni, olay tetikleyicilerinin olayları otomatik olarak olay işleyicisini çağırmasıyla gerçekleştirilebilmesidir; bu, olaylar sistem düzeyinde meydana geldiğinde olayları uygulamanın en etkili yoludur.

Benzer şekilde, posta çalışanı kapınızı çalıyor ve postayı doğrudan size teslim ederse, posta kutunuzu her gün postayla kontrol etmeniz gerekmez.

Ancak, olay dinleyicileri de anket yaparak çalışabilir. Yoklama mutlaka belirli bir değeri veya gözlemlenebilir başka bir şeyi kontrol etmek zorunda değildir; daha karmaşık olabilir. Ancak, genel olarak, oy verme noktası, bir olaya cevap verilebilecek şekilde gerçekleştiği zaman çıkarımda bulunmak demektir.

Benzer şekilde, posta çalışanınız sadece postaları bıraktığında, posta kutunuzu her gün kontrol etmeniz gerekir. Posta görevlisine kapınızı çalma talimatı verirseniz, bu yoklama işini yapmak zorunda kalmazsınız, ancak bu genellikle bir olasılık değildir.

Zincirleme olay mantığı

Birçok programlama dilinde, sadece klavyedeki bir tuşa basıldığında veya belirli bir zamanda basılan bir olayı yazabilirsiniz. Bunlar dış olaylar olsa da, onlar için anket yapmanız gerekmez. Neden?

Bunun nedeni işletim sisteminin sizin için oy vermesidir. Örneğin, Windows klavye durumu değişiklikleri gibi şeyleri kontrol eder ve bir tanesini tespit ederse olay abonelerini arayacaktır. Bu nedenle, bir klavye basın etkinliğine abone olduğunuzda, aslında anket yapan bir etkinliğe abone olan bir etkinliğe abone olursunuz.

Benzer şekilde, bir apartman kompleksi yaşadığınızı ve bir posta görevlisinin postaları ortak bir posta giriş alanına bıraktığını söyleyin. Daha sonra, işletim sistemi benzeri bir çalışan bu postayı herkes için kontrol edebilir ve bir şeyler alanların dairelerine posta gönderebilir. Bu, herkesi posta-makbuz alanını sorgulamak zorunda bırakmamaktan kurtarıyor.


Sezgim, olay dinleyicisinin olayın başlatılıp başlatılmadığını sürekli olarak kontrol ettiğini, yani senaryomda, olayın başlatıldığı her kareyi kontrol etmekten farklı olmayacağını varsayıyordu.

Sınıftaki tartışmaya dayanarak, olay dinleyicisinin farklı şekilde çalıştığı görülmektedir.

Bir olay dinleyicisi nasıl çalışır?

Eğer şüpheli olduğunuz gibi, bir olay olabilir yoklama yoluyla çalışır. Bir olay bir şekilde dış olaylar ile ilgiliyse, örneğin basıldığında bir klavye tuşu varsa, bir noktada oylama yapılması gerekir.

Bu aynı zamanda olayların yoklama ile ilgili olması gerekmediği için de geçerlidir. Örneğin, bir düğmeye basıldığında olay varsa, o zaman bu düğmenin olay dinleyicisi, bir fare tıklatmasının düğmeye bastığını belirlediğinde GUI çerçevesinin arayabileceği bir yöntemdir. Bu durumda, oylamanın, fare tıklatmasının algılanması için hala gerçekleşmesi gerekiyordu, ancak fare dinleyicisi, olay zincirleme yoluyla ilkel yoklama mekanizmasına bağlı daha pasif bir öğedir.

Güncelleme: Düşük seviye donanım oylamalarında

USB cihazlarının ve diğer modern iletişim protokollerinin, klavyeler ve fareler gibi G / Ç cihazlarının geçici topolojilerde yer almasını sağlayan etkileşimler için oldukça etkileyici bir ağ benzeri protokol kümesi olduğu ortaya çıktı .

İlginçtir ki, " kesintiler " oldukça zorunlu, senkronize şeylerdir, bu yüzden özel ağ topolojileriyle başa çıkmazlar. Bunu düzeltmek için, " kesmeler ", " kesilme işlemleri " (USB bağlamında) veya " mesaj işaretli kesmeler " (PCI bağlamında) olarak adlandırılan eşzamansız yüksek öncelikli paketlere genelleştirilmiştir . Bu protokol bir USB spesifikasyonunda açıklanmıştır:

görüntü tanımını buraya girin

- " Şekil 8-31. Toplu İşlem / Kontrol / Kesinti İşlemi Ana Durum Makinesi ", "Evrensel Seri Veri Yolu Belirtimi, Revizyon 2.0" , basılı-sayfa-222; PDF-sayfa-250 (2000-04-27)

Temel amaç, G / Ç aygıtlarının ve iletişim bileşenlerinin (USB hub gibi) temelde ağ aygıtları gibi göründüğü görülüyor. Böylece limanlarını yoklamalarını gerektiren mesajlar gönderiyorlar. Bu, özel donanım hatlarına olan ihtiyacı azaltır.

Windows gibi işletim sistemleri yoklama işlemini kendisinin işlemesi gibi görünüyor, örneğin anlatıldığı gibi MSDN belgelerine USB_ENDPOINT_DESCRIPTOR's nasıl kontrol edileceği açıklanır ne sıklıkta, Windows anketler kesme / isochronous mesajları için bir USB ana denetleyicisi:

bIntervalDeğeri kesme ve izokronik uç noktaları için yoklama aralığını içerir. Diğer uç nokta türleri için bu değer göz ardı edilmelidir. Bu değer, cihazın bellenim yapılandırmasını yansıtır. Sürücüler bunu değiştiremez.

Yoklama aralığı, cihazın hızı ve ana bilgisayar denetleyicisinin türü ile birlikte, sürücünün bir kesme veya eşzamanlı aktarma başlatması gereken sıklığı belirler. İçindeki değer bIntervalsabit bir süreyi temsil etmiyor. Göreceli bir değerdir ve gerçek yoklama frekansı, cihazın ve USB ana denetleyicisinin düşük, tam veya yüksek hızda çalışıp çalışmadığına da bağlı olacaktır.

- "USB_ENDPOINT_DESCRIPTOR yapısı" , Donanım Geliştirme Merkezi, Microsoft

DisplayPort gibi daha yeni monitör bağlantı protokolleri de aynı şekilde görünüyor:

Çok Akışlı Aktarım (MST)

  • DisplayPort Ver.1.2'ye MST (Çoklu Aktarım Aktarımı) eklendi

    • Ver.1.1a’da yalnızca SST (Tek Akışlı Aktarım) mevcuttu
  • MST, tek bir bağlayıcı üzerinde birden fazla A / V akışını taşır

    • 63 akışa kadar; "Şerit Başına Akım" değil

      • Taşınan akarsular arasında bir senkronizasyon varsayılmaz; bir akış boşluk bırakma döneminde olabilir, diğerleri ise
    • Bağlantı yönelimli bir taşıma

      • Bir akış kaynağından, bir akış aktarımının başlamasından önce AUX CHʼ'ler üzerinden Mesaj İşlemleri aracılığıyla oluşturulmuş bir hedef akış havuzuna giden yol

      • Kalan akışları etkilemeden bir akışın eklenmesi / silinmesi

görüntü tanımını buraya girin

-Slide # 14 "DisplayPortTM Ver.1.2 Genel Bakış" (2010-12-06)

Bu soyutlama, tek bir bağlantıdan 3 monitör çalıştırmak gibi bazı zarif özelliklere izin verir:

DisplayPort Çok Akışlı Aktarım ayrıca üç veya daha fazla cihazı birbirine bağlamaya izin verir ancak bunun tersine, daha az "tüketici" odaklı bir yapılandırmada: aynı anda tek bir çıkış portundan birden fazla ekranı sürmek.

- "DisplayPort" , Wikipedia

Kavramsal olarak, bundan uzak durmanın amacı, yoklama mekanizmalarının daha genel işlevler istediğinizde harika olan daha genel seri haberleşmelere izin vermesidir. Bu nedenle, donanım ve işletim sistemi mantıksal sistem için çok oylama yapar. Daha sonra, etkinliklere abone olan tüketiciler, kendi yoklama / mesaj iletme protokollerini yazmak zorunda kalmadan, kendileri için düşük seviyeli sistem tarafından işlenen bu ayrıntıların tadını çıkarabilirler.

Sonuçta, tuş basımları gibi olaylar, yazılım düzeyindeki zorunlu olay başlatma mekanizmasına geçmeden önce oldukça ilginç bir olay dizisinden geçiyor gibi görünmektedir.


Son paragrafınıza gelince, genellikle düşük düzeyde yoklama yapılmaz, işletim sistemi çevre aygıtları tarafından tetiklenen donanım kesintilerine tepki verir. Bir bilgisayarda genellikle birçok bağlı cihaz vardır (fare, klavye, disk sürücüleri, ağ kartları) ve bunların yoklanması çok verimsiz olacaktır.
Barmar

Bununla birlikte, posta teslimindeki analojileriniz tam olarak üst düzeydeki etkinliği nasıl açıklayacağımdır.
Barmar

1
@Barmar Ya, aygıtlar USB bağlantılarına taşındığında, yoklama (doğrudan bir USB klavyenin yaptığı gibi) talep etmekten (bir PS / 2 klavyenin yaptığı gibi) kesinti üretmelerinden nasıl geçtikleri hakkında bir çok konuşma yapıldı ve bazı kaynaklar hak talebinde bulundu. Yoklama CPU tarafından yapıldı. Ancak, diğer kaynaklar , yoklamayı CPU için bir kesmeye dönüştüren özel bir denetleyici üzerinde yapıldığını iddia ediyor.
Nat

@Barmar Hangisinin doğru olduğunu biliyor musunuz? Muhtemelen CPU'nun yoklama işlemini diğerlerinden daha fazla yaptığını iddia eden daha fazla kaynak gördüm, ancak bunun için özel bir denetleyici daha mantıklı görünüyor. Yani, Arduino'nun ve diğer gömülü aygıtların, yoklama işlemini gerçekleştirmesi için CPU'yu gerektirme eğiliminde olduğunu düşünüyorum, ancak x86 tipi aygıtlar hakkında hiçbir şey bilmiyorum.
Nat

1
Herhangi biri onaylayabiliyorsa bu cevabı güncelleyebilsem diye düşünüyorum , örneğin USB ile bağlı olan modern I / O cihazlarının CPU'nun kontrolünü atlayarak doğrudan belleğe yazdığını (bu nedenle hızlı / verimli olmalarının ve güvenliklerin ne olduğunu zaman zaman tehlike ). Ardından, yeni mesajları kontrol etmek için hafızayı yoklamak için modern bir işletim sistemi gerekir.
Nat

8

Çekme vs İtme

Bir etkinliğin olup olmadığını veya belirli bir duruma ulaşılıp ulaşılmadığını kontrol etmek için iki ana strateji vardır. Örneğin, önemli bir teslimat için beklediğinizi düşünün:

  • Çekin : her 10 dakikada bir, posta kutunuza gidin ve teslim edilip edilmediğini kontrol edin,
  • Gönder : teslimat görevlisine teslimatı yaptıklarında sizi aramasını söyleyin.

Çekme (ayrıca yoklama denir) yaklaşımı basittir: Herhangi bir özel özellik olmadan bunu uygulayabilirsiniz. Diğer yandan, onlar için gösterilecek hiçbir şey olmadan ekstra kontroller yapma riskiniz olduğundan, genellikle daha az etkilidir.

Öte yandan, itme yaklaşımı genellikle daha verimlidir: kodunuz yalnızca yapacak bir şeyi olduğunda çalışır. Öte yandan, bir dinleyici / gözlemci / geri arama 1 kaydetmeniz için bir mekanizma bulunmasını gerektirir .

1 Postacım maalesef böyle bir mekanizmaya sahip değil.


1

Spesifik olarak birliktelik hakkında - her kareyi sorgulamaktan ziyade oyuncunun girişini kontrol etmenin başka bir yolu yoktur. Bir olay dinleyicisi oluşturmak için, oylama yapmak için hala "olay sistemi" veya "olay yöneticisi" gibi bir nesneye ihtiyacınız olacaktır, bu nedenle sorunu yalnızca farklı bir sınıfa itecektir.

Bir etkinlik yöneticisine sahip olduğunuzda, her karenin girişini oylayan sadece bir sınıfınız vardır, ancak bu açıkça göze çarpan bir performans avantajı sağlamaz, çünkü bu sınıfın dinleyiciler üzerinde yinelemeleri ve onları oyuna bağlı olarak çağırmaları gerekir. tasarım (olduğu gibi, kaç dinleyici var ve müzikçaların girişi ne sıklıkta kullanıyorsa), aslında daha maliyetli olabilir.

Bütün bunların dışında, altın kuralı unutmayın - erken optimizasyon, özellikle her kareyi oluşturma işleminin çok pahalı olduğu video oyunlarında özellikle geçerli olan tüm kötülüklerin köküdür , bunun gibi küçük senaryo optimizasyonları tamamen önemsizdir.


Merkezi bir olay döngüsünü optimizasyon olarak görmemiştim, ancak kod tabanının her yerine yayılan sorgulamanın aksine daha okunaklı, anlaşılır bir kod yazmak gibi. Aynı zamanda “sentetik” olaylara ve oyun motorunu oylamadan gelmeyen olaylara da izin verir.
BlackJack

@ BlackJack Katılıyorum ve genellikle kendim bu şekilde kodlar, ancak OP performans hakkında sordu. Btw, Birlik, hemen hemen her yerde statik fonksiyonlara sahip olmak gibi şaşırtıcı bir şekilde pek çok şüpheli kod tasarımı kararına sahiptir.
Dunno

1

İşletim Sisteminizde / Çerçevenizde, düğmeye basma veya zamanlayıcı taşması veya mesajın gelmesi gibi olayları işleyen bazı destekleriniz olmadığı sürece, bu Olay Dinleyici pıtağını yine de yoklama kullanarak (altta bir yerde) uygulamak zorunda kalacaksınız.

Ancak bu tasarım modelinden uzak durmayın, çünkü orada hemen bir performans avantajınız yoktur. Olay işleme desteğinin altını çizip desteklemediğinizden bağımsız olarak kullanmanızın nedenleri aşağıdadır.

  1. Kod daha temiz ve daha yalıtılmış görünüyor (doğru şekilde uygulanmışsa)
  2. Olay işleyicilerini temel alan kod, daha iyi durma değişikliklerini daha iyi yapar (normalde yalnızca bazı olay işleyicilerini değiştirdiğiniz için)
  3. Etkinlik desteğinin altını çizerek platforma geçerseniz - mevcut etkinlik işleyicilerinizi yeniden kullanabilir ve yoklama kodundan kurtulabilirsiniz.

Sonuç - tartışmaya katıldığınız için şanslısınız ve oy kullanma alternatiflerinden birini öğrendiniz. Bu konsepti uygulamada uygulamak için bir fırsat arayın ve kodun ne kadar zarif olabileceğini takdir edeceksiniz.


1

Çoğu olay döngüsü , işletim sistemi tarafından sağlanan bazı yoklama çoklayıcı ilkellerinin üzerine inşa edilmiştir. Linux'ta, bu ilkel genellikle poll(2) sistem çağrısıdır (ama eskisi olabilir select). GUI uygulamalarında, ekran sunucusu (örn. Xorg veya Wayland ), uygulamanızla iletişim kuruyor (bir soket (7) veya boru (7) ). Ayrıca X Pencere Sistem Protokolleri ve Mimarisi hakkında da bilgi edinin .

Bu tür oy verme ilkelleri etkilidir; Çekirdek pratikte bazı girdiler yapıldığında işleminizi uyandıracak (ve bazı kesmeler işlendiğinde).

Somut bir şekilde, widget araç seti kütüphaneniz görüntü sunucunuzla iletişim kurar, mesajları bekler ve bu mesajları widget'larınıza gönderir. Qt veya GTK gibi araç seti kütüphaneleri oldukça karmaşıktır (milyonlarca satır kaynak kodu satırı). Klavyeniz ve fareniz yalnızca görüntüleme sunucusu işlemiyle kullanılır (bu tür girişleri istemci uygulamalarına gönderilen olay iletilerine çevirir).

(Ben sadeleştiriyorum; aslında işler çok daha karmaşık.)


1

Tamamen yoklama tabanlı bir sistemde, belirli bir işlemin ne zaman gerçekleşeceğini bilmek isteyebilecek alt sistem, işlemin gerçekleşebileceği herhangi bir zamanda bir kod çalıştırması gerekecektir. Gerçekleşmesi gerekmeyen benzersiz olayların her birinin 10 ms içinde tepki vermesi gereken birçok alt sistem varsa, etkinliklerinin gerçekleşip gerçekleşmediğini en az 100 kez / saniye kontrol etmeleri gerekir. Bu alt sistemler farklı iş parçacığı (veya daha kötüsü, işlemler) işlemindeyse, bu tür bir iş parçacığı ya da işlem 100x / saniye arasında geçişi gerektirir.

Uygulamaların izleyeceği şeylerin birçoğunun benzer olması durumunda, merkezi bir izleme alt sistemine (belki de masaya dayalı) sahip olmak daha etkili olabilir, bu da birçok şeyi izleyebilir ve herhangi birinin değişip değişmediğini gözlemleyebilir. Örneğin, 32 anahtar varsa, bir platformda bir kerede 32 anahtarın tümünü aynı anda okuyabilecek bir fonksiyon olabilir, bu da monitör kodunun yoklama arasında herhangi bir anahtarın değişip değişmediğini kontrol etmesini mümkün kılar. hangi kodun kendileriyle ilgilenebileceğinden endişe edin.

Bir şey değiştiğinde bildirimde bulunmak isteyen birçok alt sistem varsa, özel bir izleme alt sistemine sahip olmak, olaylar ilgilendikleri zaman diğer alt sistemlere haber vermek, her bir alt sistemin kendi etkinliklerini sorgulamasından daha verimli olabilir. Bununla birlikte, hiç kimsenin herhangi bir olayla ilgilenmediği durumlarda özel bir izleme alt sistemi kurmak, saf bir kaynak israfını temsil edecektir. Olaylarla ilgilenen yalnızca birkaç alt sistem varsa, ilgilendikleri olayları izlemelerinin maliyeti, genel amaçlı özel bir izleme alt sistemi kurma maliyetinden daha düşük olabilir, ancak nokta farklı platformlar arasında önemli ölçüde değişecektir.


0

Bir olay dinleyicisi bir mesajı bekleyen bir kulak gibidir. Olay gerçekleştiğinde, olay dinleyicisi olarak seçilen alt rutin olay argümanlarını kullanarak çalışır.

Her zaman iki önemli veri vardır: olayın gerçekleştiği an ve bu olayın gerçekleştiği nesne. Diğer tartışma, olanlar hakkında daha fazla veri.

Olay dinleyicisi, gerçekleşenin tepkisini belirtir.


0

Bir Etkinlik Dinleyicisi Yayınlama / Abone Olma Modelini takip eder (abone olarak)

Bir yayın nesnesi, en basit haliyle, bir şeyin yayınlanması gerektiğinde uygulanacak olan abonelerin talimatlarının bir listesini tutmaktadır.

Bu, subscribe(x)x'in olay işleyicisinin olayı işlemek için nasıl tasarlandığına bağlı olduğu bir tür yönteme sahip olacaktır . Abone (x) çağrıldığında, abonelerin talimatları / referansları yayıncı listesine x eklenir.

Yayıncı, olayı ele almak için mantığın tümünü veya bir kısmını içerebilir. Olay gerçekleştiğinde abonelere, belirtilen mantıkla onları bildirmesi / dönüştürmesi basit bir referans gerektirebilir. Hiçbir mantık içermeyebilir ve olayı işleyebilecek abone nesneleri (yöntemler / olay dinleyicileri) gerektirebilir. Her ikisinin bir karışımını içermesi daha olasıdır.

Bir olay meydana geldiğinde, yayıncı abone listesi / referans listesindeki her bir madde için mantığını tekrar eder ve yürütür.

Bir olay işleyicisi ne kadar karmaşık olursa olsun, özünde bu basit kalıbı izler.

Örnekler

Bir olay dinleyicisi örneği için, olay işleyicisinin subscribe () yöntemine bir yöntem / işlev / instruc / olay dinleyici sağlarsınız. Olay işleyicisi, yöntemi abone geri arama listesine ekler. Bir olay meydana geldiğinde, olay işleyicisi listesinin üzerinde yinelenir ve her geri aramayı yürütür.

Gerçek bir dünya örneği için, Stack Exchange bültenine abone olduğunuzda, profilinize bir referans abone veritabanına eklenecektir. Bülten yayınlanma zamanı geldiğinde, referans bülten şablonunu doldurmak için kullanılacak ve e-postanıza gönderilecektir. Bu durumda, x yalnızca size bir referanstır ve yayıncının tüm aboneler için kullanılan bir dizi dahili talimatı vardır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.