Megosztás a következőn keresztül:


A frissített .NET Core-eseményminta

Előző

Az előző cikk a leggyakoribb eseménymintákat ismertette. A .NET Core lazább mintával rendelkezik. Ebben a verzióban a EventHandler<TEventArgs> definíció már nem rendelkezik azokkal a korlátozásokkal, amelyekből TEventArgsSystem.EventArgsaz osztálynak származnia kell.

Ez növeli a rugalmasságot, és visszamenőlegesen kompatibilis. Kezdjük a rugalmassággal. A System.EventArgs osztály egy metódust vezet be: MemberwiseClone()ez hozza létre az objektum sekély másolatát. Ennek a metódusnak tükrözést kell használnia annak érdekében, hogy a funkcióját bármely, a forrásból EventArgsszármaztatott osztályhoz megvalósítsa. Ez a funkció egyszerűbben hozható létre egy adott származtatott osztályban. Ez gyakorlatilag azt jelenti, hogy a System.EventArgs-ből való származtatás olyan kényszer, amely korlátozza a terveket, de nem biztosít további előnyöket. Valójában módosíthatja FileFoundArgs a definíciókat, és SearchDirectoryArgs így azok nem származnak.EventArgs A program pontosan ugyanúgy fog működni.

Ha még egy módosítást szeretne végezni, a szerkezetet is módosíthatja SearchDirectoryArgs :

internal struct SearchDirectoryArgs
{
    internal string CurrentSearchDirectory { get; }
    internal int TotalDirs { get; }
    internal int CompletedDirs { get; }

    internal SearchDirectoryArgs(string dir, int totalDirs, int completedDirs) : this()
    {
        CurrentSearchDirectory = dir;
        TotalDirs = totalDirs;
        CompletedDirs = completedDirs;
    }
}

A további módosítás az, hogy meghívja a paraméter nélküli konstruktort, mielőtt az összes mezőt inicializáló konstruktort beírja. E kiegészítés nélkül a C# szabályai azt jelentik, hogy a tulajdonságok a hozzárendelésük előtt érhetők el.

Az osztályt (referenciatípust) ne módosítsa FileFoundArgs szerkezetre (értéktípusra). Ennek az az oka, hogy a megszakítás kezelésére szolgáló protokoll megköveteli az eseményargumentumok hivatkozással történő átadását. Ha ugyanezt a módosítást hajtotta végre, a fájlkeresési osztály soha nem tudta megfigyelni az esemény előfizetői által végrehajtott módosításokat. A struktúra új példánya minden előfizető számára használható, és ez a másolat más másolat lenne, mint a fájlkeresési objektum által látott másolat.

Most tekintsük át, hogyan lehet ez a módosítás visszamenőlegesen kompatibilis. A kényszer eltávolítása nem érinti a meglévő kódot. A meglévő eseményargumentumtípusok továbbra is a következőből System.EventArgsszármaznak: . A visszamenőleges kompatibilitás az egyik fő oka annak, hogy továbbra is származni fognak a programból System.EventArgs. A meglévő esemény-előfizetők a klasszikus mintát követő esemény előfizetői lesznek.

Hasonló logikát követve a most létrehozott eseményargumentum-típusok nem rendelkeznének előfizetőkkel egyetlen meglévő kódbázisban sem. Azok az új eseménytípusok, amelyek nem származnak, System.EventArgs nem szakítják meg ezeket a kódbázisokat.

Események az Async-előfizetőkkel

Egy utolsó mintát kell megtanulnia: Hogyan írhat helyesen az aszinkron kódot hívó esemény-előfizetőket. A kihívást az aszinkronról szóló cikkben ismertetjük, és várjuk. Az aszinkron metódusok érvénytelen visszatérési típussal rendelkezhetnek, de ez erősen elriasztható. Amikor az esemény-előfizetői kód aszinkron metódust hív meg, nincs más választása, mint létrehozni egy metódust async void . Az eseménykezelő aláírásához szükség van rá.

Ezt az ellentétes útmutatást össze kell hangolnia. Valahogy létre kell hoznia egy biztonságos async void módszert. A megvalósítandó minta alapjai az alábbiak:

worker.StartWorking += async (sender, eventArgs) =>
{
    try
    {
        await DoWorkAsync();
    }
    catch (Exception e)
    {
        //Some form of logging.
        Console.WriteLine($"Async task failure: {e.ToString()}");
        // Consider gracefully, and quickly exiting.
    }
};

Először figyelje meg, hogy a kezelő aszinkron kezelőként van megjelölve. Mivel egy eseménykezelő delegálttípushoz van rendelve, érvénytelen visszatérési típussal fog rendelkezni. Ez azt jelenti, hogy a kezelőben látható mintát kell követnie, és nem szabad kivételeket kivennie az aszinkron kezelő környezetéből. Mivel nem ad vissza tevékenységet, nincs olyan tevékenység, amely a hibás állapot beírásával jelentheti a hibát. Mivel a metódus aszinkron, a metódus nem tudja egyszerűen kivenni a kivételt. (A hívó metódus továbbra is végrehajtás alatt áll, mert az async.) A futtatókörnyezet tényleges viselkedése eltérően lesz definiálva a különböző környezetekben. Megszakíthatja a szálat vagy azt a folyamatot, amely a szál tulajdonosa, vagy meghatározhatatlan állapotban hagyhatja a folyamatot. Mindezek a lehetséges eredmények rendkívül nemkívánatosak.

Ezért érdemes az aszinkron tevékenység várakozási utasítását a saját próbablokkjában becsomagolni. Ha ez hibát okoz, naplózhatja a hibát. Ha olyan hiba, amelyből az alkalmazás nem tud helyreállni, gyorsan és kecsesen kiléphet a programból

Ezek a .NET-eseményminta fő frissítései. Számos példát láthat a korábbi verziókra a tárakban, amellyel dolgozik. Azonban meg kell értenie, hogy mik a legújabb minták is.

A sorozat következő cikke segít különbséget tenni a használat delegates és events a tervezés között. Ezek hasonló fogalmak, és ez a cikk segít a legjobb döntés meghozatalában a programok számára.

Következő