Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
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 azzal a korlátozással, hogy TEventArgsSystem.EventArgsszármazó osztálynak kell lennie.
Ez növeli a rugalmasságot, és visszamenőlegesen kompatibilis. Kezdjük a rugalmassággal. A megvalósítás System.EventArgs egy metódusban System.Object definiált metódust használ: MemberwiseClone()ez hozza létre az objektum sekély másolatát. Ennek a metódusnak reflexiót kell használnia ahhoz, hogy bármelyik EventArgs-ből származó osztályban megvalósítsa a funkcionalitását. 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 nyújt semmilyen extra előnyt. Valójában módosíthatja a FileFoundArgs és SearchDirectoryArgs definícióit, hogy ne EventArgs-ből származzanak. A program pontosan ugyanúgy működik.
Egy másik lehetőségként a SearchDirectoryArgs-t is módosíthatja egy struktúrává, ha még egy változtatást végez.
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 változá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 előtt érhetők el.
Ne változtassa meg a FileFoundArgs-t osztályról (referenciatípusról) struktúrára (értéktípusra). A törlés kezelésének protokollja megköveteli, hogy az eseményargumentumokat hivatkozással adja á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 System.EventArgsszármaznak. A visszamenőleges kompatibilitás az egyik fő oka annak, hogy továbbra is System.EventArgs-ból származtatják. A meglévő esemény-előfizetők a klasszikus mintát követő esemény előfizetői.
Hasonló logikát követve a most létrehozott eseményargumentum-típusok nem rendelkeznek előfizetőkkel egyetlen meglévő kódbázisban sem. Az új eseménytípusok, amelyek nem System.EventArgs származnak, 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 aszinkron kódot hívó esemény-feliratkozókat. A kihívást aszinkronról szóló cikkben ismertetjük, és várjuk. Az aszinkron metódusok érvénytelen visszatérési típussal rendelkezhetnek, de ez nem ajánlott. 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 async void metódust. 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 hozni egy biztonságos async void metódust. A megvalósítandó minta alapjai a következő kódban jelennek meg:
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 rendelkezik. 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 kivenni a kivételt. (A hívó metódus folytatja a végrehajtást, mert async.) A futtatókörnyezet tényleges viselkedése eltérően van definiálva a különböző környezetekben. Megszakíthatja a szálat vagy azt a folyamatot, amely a szál tulajdonosa, vagy a folyamatot meghatározatlan állapotban hagyhatja. Mindezek a lehetséges eredmények rendkívül nemkívánatosak.
Az aszinkron tevékenységhez tartozó await kifejezést a saját próbablokkjában kell becsomagolnia. Ha hibás feladatot okoz, naplózhatja a hibát. Ha ez egy hiba, amelyből az alkalmazás nem tud helyreállni, gyorsan és kecsesen kiléphet a programból
Ez a cikk a .NET-eseményminta főbb frissítéseit ismertette. 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 minta kész kódját a Program.cs láthatja.
A sorozat következő cikke segít megkülönböztetni a delegates és a events használatát a terveiben. Ezek hasonló fogalmak, és ez a cikk segít a legjobb döntést hozni a programokhoz.