Delegate vs Event
2014-04-01T08:09:59+02:00
2014-04-01T17:55:47+02:00
2022-07-19T02:51:56+02:00
  • Köszi a kimerítő választ, ismét tanultam :)

    Tulajdon képen konkrét kérdés nincs, csupán a nemrég leírt probléma megoldására várok jobbnál jobb ötleteteket, hátha van valakinek valami jobb mint az enyém, ami biztosan nem állítja meg a kommunikációt.

    "Gyári példaként erre ld. a soros port DataReceived eseményét: ez úgy működik, hogy fut a programod (GUI-szál), amikor viszont esemény jön, akkor a ThreadPool-ról indul egy új szál, és azon fut az esemény (nem a GUI-szálon)."

    Ez a megoldás tetszik, eddig én az eseményből indítottam új szálat.
    Mutasd a teljes hozzászólást!
  • Lehet valahogy eventet is meghívni asincron módon?

    Wo Hu kolléga hozzászólásához csak annyit tennék hozzá, hogy ha egy szálad van - márpedig az elakadó kommunikáció erre enged következtetni -, attól még ugyanúgy meg fog állni a kommunikáció, amíg a Grid frissül. Tehát több szál használatával tudod elkerülni az akadást: egy szálon fut a GUI, egy másikon a kommunikáció.

    Gyári példaként erre ld. a soros port DataReceived eseményét: ez úgy működik, hogy fut a programod (GUI-szál), amikor viszont esemény jön, akkor a ThreadPool-ról indul egy új szál, és azon fut az esemény (nem a GUI-szálon).

    Tehát én annyival egészíteném ki Wo Hu kolléga ajánlását, hogy célszerű a kommunikációt egy háttér-thread-en futtatni, az iratkozik fel arra az eseményre, aminek a hatására a Grid-et frissíteni kell, és amikor ez az esemény bekövetkezik, az tárolja el a frissítendő állapotot, majd a GUI valahogyan (időzítő vagy INotifyPropertyChanged) frissül az új állapotnak megfelelően (ahogy már elhangzott). A lényeg, hogy így elkülönül az esetleges lassú, elakadó GUI-frissítés a tényleges kommunikációtól.

    Szerk.: Megcsináltam a grid feltöltését aszinkron módon, úgy tökéletes

    Igazából ezt írtam le részletesen, de akkor végül sikerült megoldani? Ha igen, akkor továbbra sem értem, mi a kérdés.
    Mutasd a teljes hozzászólást!
  • Igen, .NET-ről van szó.

    Ez is egy jó ötlet köszi.
    Mutasd a teljes hozzászólást!
  • Lehet valahogy eventet is meghívni asincron módon?

    Ha feliratkozol egy event-re, akkor az oprendszer gondoskodik róla, hogy a programod értesüljön, amikor az event "elsül". Én az event handler metódusban nem frissíteném a megjelentést (a gridet), csupán eltárolnám az új állapotot, valamint beállítanék egy flag-et, hogy frissíteni kell majd a gridet.

    A vizuális frissítést pedig csak adott időközönként végezném el: mondjuk másodpercenként ellenőrízném, hogy a flag true-ra lett-e állítva. Ha igen, akkor frissítem a gridet.

    VAGY

    implementálod az INotifyPropertyChanged-et (ha .NET-ről van szó). Az szebb megoldás, mindenféle időzítgetés nélkül.
    Mutasd a teljes hozzászólást!
  • Köszi válaszod!

    Igen, igazad van! Annyiban módosítanám a leírtakat hogy a delegate alatt callback-re gondoltam, elnézést a tudatlanságomért!

    Igen, a timer-es elképzelés nem rossz, bár én személy szerint nem szeretem őket.

    Konkrét példát nemigazán tudok mondani, inkább a legfontosabb kritérium az az lenne hogy a kommunikációt ne blokkolhassa semmi sem.
    Kicsit érthetőbben:
    A harveren kapok egy bementi jelet, az meghív egy eventet, ami a formon feltölt egy gridet. A grid feltöltésig egy pillanatra megáll a kommunikáció. Megcsináltam a grid feltöltését aszinkron módon, úgy tökéletes. Lehet valahogy eventet is meghívni asincron módon?
    Próbálkoztam a SyncronisationContext.Post-al, ami elvileg valami hasonlót valósít meg, de viszont eléggé érdekes hibábka futottam bele, viszond a Send()-el nem volt problémám
    Mutasd a teljes hozzászólást!
  • mindkettővel az a probléma, hogy a szolgáltatást felhasználó rétegtől függ a szolgáltató réteg. azaz ha beraksz egy hibás delegate-t (vagy event handlert) a gui-ból, és lehívsz a kommunikációs rétegbe, akkor a hívás el fog bukni, pedig nem hibás a hívott kód.

    ne trükközz delegate-vel meg callback-ekkel, simán hívd meg az adatokat visszaadó függvényt, aztán a visszakapott adatokat meg átadhatod az ui rétegben a megfelelő membernek.
    Mutasd a teljes hozzászólást!
  • Én sem tudok teljesen kiigazodni a kérdésen. A delegate és az event nem egymás alternatívái (az event is delegate-et használ, ugye), ill. egyéb módon is tudnak a rétegek kommunikálni, ezért én teljesen más oldalról fognám meg a kérdést: mi a feladat, hogy szeretnéd, hogy működjön?

    Pl. egyéb lehetőség: a külső eszközök publikus property-ken keresztül non-stop elérhetővé teszik az állapotukat, és egy egyszerű timer bizonyos időközönként ennek megfelelően frissíti a GUI-t. Ennek megvalósításához egyik sem kell.

    Szóval picit nehéz így általánosságban véleményt mondani ilyen kérdésben: a részletektől függ, milyen utat célszerű választani.
    Mutasd a teljes hozzászólást!
  • Bocsi lehet hogy hülyeséget írtam, tulajdonkép valahogy így kell elképzelni:

    Delegate:

    public delegate void Callback_InputRefresh_Delegate(); Callback_InputRefresh_Delegate CLB_InputRefresh = null; private bool Callback_InputRefresh() { if (CLB_InputRefresh != null) { CLB_InputRefresh(); return true; } return false; } public void SetCallbackFunctions(Callback_InputRefresh_Delegate pInputRefresh) { if (pInputRefresh != null) CLB_InputRefresh = pInputRefresh; }
    Így a felsőbb osztályban meghívódik a
    SetCallbackFunctions
    által megadott metódus.

    Event:

    public delegate void Callback_InputRefresh_Delegate(); public event Callback_InputRefresh_Delegate InputRefresh;
    private void InputRefresh() {
    if (this.InputRefresh != null) { this.InputRefresh(); } }

    Valami ilyesmit kellene elképzelni
    Mutasd a teljes hozzászólást!
  • Az miaz hogy delegate-tel vagy event-tel? Mutathatnál egy-egy példát, hogy mégis mire gondolsz.
    Mutasd a teljes hozzászólást!
  • Sziasztok!

    Egy olyan kérdésben kérném ki a véleményeteket, amire nem találtam teljesen egyértelmű pro-kontra érveket, ezért gondoltam kikérem a tapasztaltabbak véleményét is.

    Amit tudni kell:
    Ipari alkalmazásról van szó, ahol különféle hardware-vel kell kommunikálni általában soros porton, de van hogy ethernet-en keresztül. Az eszközök általában passzív eszközök, ami annyit takar hogy folyamatosan le kell kérni az állapotát, mert magától nem kezdeményez kommunikációt.
    A kommunikáció meg a kapcsolatkezelés megvan egy külön osztályban, amit a felsőbb rétegekben(GUI) használok.

    Abban kérnék véleményeket hogy a felsőbb réteg és a kommunikációs rétek közötti kommunikációt delegate-vel vagy event-vel érdemesebb-e megvalósítani, és jó lenne érvekkel is alátámasztani. Én személy szerint az even-et részesítem előnyben, de elfogadom a kritikát is.

    Előre is köszönöm a hozzászólásokat.
    Mutasd a teljes hozzászólást!
abcd