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


Az állapotváltozások ismertetése

Ez a témakör a csatornák állapotait és áttűnéseit, a csatornaállapotok strukturálásához használt típusokat és azok implementálását ismerteti.

Állapotgépek és csatornák

A kommunikációval foglalkozó objektumok, például a szoftvercsatornák általában olyan állapotgépet mutatnak be, amelynek állapotváltásai a hálózati erőforrások kiosztásához, a kapcsolatok létrehozásához vagy elfogadásához, a kapcsolatok bezárásához és a kommunikáció megszüntetéséhez kapcsolódnak. A csatornaállapot-gép egy kommunikációs objektum állapotainak egységes modelljét biztosítja, amely elvonja az objektum mögöttes implementációját. Az ICommunicationObject interfész állapotok, állapotáttűnési módszerek és állapotáttraszt-események készletét biztosítja. Minden csatorna, csatornagyár és csatornafigyelő implementálja a csatornaállapot-gépet.

A bezárt, a bezárt, a hibás, a megnyitott és a megnyitás események egy külső megfigyelőt jeleznek az állapotváltás után.

Az Abort, Close és Open metódusok (és azok aszinkron megfelelői) állapotváltásokat okoznak.

Az állapottulajdonság az aktuális állapotot adja vissza a következő szerint CommunicationState:

ICommunicationObject, CommunicationObject, and States and State Transition

A ICommunicationObject rendszer létrehozva állapotban indul el, ahol a különböző tulajdonságai konfigurálhatók. Miután megnyitott állapotban van, az objektum használható üzenetek küldéséhez és fogadásához, de tulajdonságai nem módosíthatók. A záró állapotban az objektum már nem tudja feldolgozni az új küldési vagy fogadási kéréseket, de a meglévő kéréseknek lehetősége van a befejezésre, amíg el nem éri a bezárási időtúllépést. Ha helyrehozhatatlan hiba történik, az objektum a hibás állapotba kerül, ahol a hiba információi alapján megvizsgálható, és végül bezárható. Zárt állapotban az objektum lényegében elérte az állapotgép végét. Ha egy objektum egyik állapotról a másikra vált, az nem kerül vissza az előző állapotba.

Az alábbi ábrán az állapotok és az ICommunicationObject állapotváltások láthatók. Az állapotáttűnéseket a három módszer egyikének meghívása okozhatja: Megszakítás, Megnyitás vagy Bezárás. Ezeket más implementációspecifikus metódusok meghívása is okozhatja. A hibás állapotra való áttérés a kommunikációs objektum megnyitásakor vagy megnyitása után előforduló hibák következménye lehet.

Minden ICommunicationObject a Létrehozott állapotban kezdődik. Ebben az állapotban az alkalmazás a tulajdonságainak beállításával konfigurálhatja az objektumot. Ha egy objektum a Létrehozástól eltérő állapotban van, az nem módosítható.

Dataflow diagram of the channel state transition.
1. ábra Az ICommunicationObject állapotgép.

A Windows Communication Foundation (WCF) egy absztrakt alaposztályt CommunicationObject biztosít, amely implementálja ICommunicationObject és a csatornaállapot-gépet. Az alábbi ábra egy módosított állapotdiagram, amely a következőre CommunicationObjectjellemző. Az állapotgép mellett ICommunicationObject további metódusok meghívásának időzítését CommunicationObject is megjeleníti.

Dataflow diagram of CommunicationObject implementation state changes. 2. ábra. Az ICommunicationObject állapotgép CommunicationObject implementációja, beleértve az események hívásait és a védett metódusokat.

ICommunicationObject események

CommunicationObject a által definiált ICommunicationObjectöt eseményt teszi elérhetővé. Ezek az események kódhoz vannak tervezve, a kommunikációs objektum használatával, hogy értesüljenek az állapotváltásokról. A fenti 2. ábrán látható módon minden esemény egyszer aktiválódik, miután az objektum állapota az esemény által elnevezett állapotra vált. Mind az öt esemény a EventHandler következő típusú:

public delegate void EventHandler(object sender, EventArgs e);

A megvalósítás során a CommunicationObject küldő maga CommunicationObject , vagy bármi, amit feladóként átadtak a CommunicationObject konstruktornak (ha a konstruktor túlterhelt volt). Az EventArgs paraméter emindig EventArgs.Emptyaz .

Származtatott objektumvisszahívások

Az öt esemény mellett nyolc védett virtuális módszert is deklarál, CommunicationObject amelyek lehetővé teszik egy származtatott objektum visszahívását az állapotváltások előtt és után.

A CommunicationObject.Open metódusokhoz három CommunicationObject.Close ilyen visszahívás tartozik. Például annak megfelelő CommunicationObject.OpenCommunicationObject.OnOpening, CommunicationObject.OnOpenés CommunicationObject.OnOpened. CommunicationObject.Close A hozzájuk tartozó metódusok a CommunicationObject.OnClose, CommunicationObject.OnClosingés CommunicationObject.OnClosed a metódusok.

Hasonlóképpen, a CommunicationObject.Abort metódusnak van egy megfelelő CommunicationObject.OnAbort.

Bár CommunicationObject.OnOpen, CommunicationObject.OnCloseés CommunicationObject.OnAbort nincs alapértelmezett implementációja, a többi visszahívás rendelkezik egy alapértelmezett implementációval, amely az állapotgép helyességéhez szükséges. Ha felülbírálja ezeket a metódusokat, mindenképpen hívja meg az alap implementációt, vagy cserélje le megfelelően.

CommunicationObject.OnOpening, CommunicationObject.OnClosing és CommunicationObject.OnFaulted aktiválja a megfelelő CommunicationObject.Opening, CommunicationObject.Closing és CommunicationObject.Faulted eseményeket. CommunicationObject.OnOpened és CommunicationObject.OnClosed állítsa be az objektum állapotát Megnyitott és Bezárt állapotra, majd indítsa el a megfelelő CommunicationObject.Opened és CommunicationObject.Closed az eseményeket.

Állapotáttrasztálási módszerek

CommunicationObject az Abort, a Close és a Open implementációit biztosítja. Emellett egy hibametódust is biztosít, amely állapotváltást okoz a hibás állapotra. A 2. ábra az ICommunicationObject állapotgépet mutatja be az azt okozó metódus által címkézett minden egyes áttűnéssel (a címkézetlen áttűnések az utolsó címkével ellátott áttűnést okozó metódus implementációja alatt történnek).

Feljegyzés

A kommunikációs állapot lekérése/készletei minden CommunicationObject implementációja szálszinkronizálásra kerül.

Konstruktor

CommunicationObject Három konstruktort biztosít, amelyek mindegyike a Létrehozott állapotban hagyja az objektumot. A konstruktorok a következők:

Az első konstruktor egy paraméter nélküli konstruktor, amely egy objektumot használó konstruktor túlterhelésére delegál:

protected CommunicationObject() : this(new object()) { … }

Az objektumot használó konstruktor ezt a paramétert használja a zárolandó objektumként a kommunikációs objektum állapotához való hozzáférés szinkronizálása során:

protected CommunicationObject(object mutex) { … }

Végül egy harmadik konstruktor egy további paramétert használ, amelyet az események aktiválásakor ICommunicationObject a feladó argumentumaként használnak.

protected CommunicationObject(object mutex, object eventSender) { … }

Az előző két konstruktor erre állította be a feladót.

Metódus megnyitása

Előfeltétel: Az állapot létrejön.

Állapot utáni: Az állapot meg van nyitva vagy hibás. Kivételt okozhat.

Az Open() metódus megpróbálja megnyitni a kommunikációs objektumot, és megnyitja az állapotot. Ha hibát tapasztal, az állapotot hibásnak állítja be.

A metódus először ellenőrzi, hogy az aktuális állapot létre van-e hozva. Ha az aktuális állapot megnyílik vagy meg van nyitva, a rendszer egy InvalidOperationException. Ha az aktuális állapot bezárva vagy bezárva van, akkor a rendszer egy CommunicationObjectAbortedException olyan állapotot ad, ha az objektum le lett állítva, és ObjectDisposedException egyéb esetben. Ha az aktuális állapot hibás, a rendszer egy CommunicationObjectFaultedException.

Ezután az állapotot a Megnyitás értékre állítja, és meghívja az OnOpening() (amely meghívja a megnyitási eseményt), az OnOpen() és az OnOpened() parancsot ebben a sorrendben. Az OnOpened() a Megnyitott állapotot állítja be, és a Megnyitott eseményt állítja be. Ha ezek közül bármelyik kivételt okoz, Az Open()meghívja a Fault() függvényt, és lehetővé teszi a kivétel buborék felbuborását. Az alábbi ábrán részletesebben látható a Megnyitás folyamat.

Dataflow diagram of ICommunicationObject.Open state changes.
Az OnOpen metódus felülbírálása egyéni nyitott logika implementálásához, például belső kommunikációs objektum megnyitásához.

Metódus bezárása

Előfeltétel: Nincs.

Állapot utáni állapot: Az állapot lezárult. Kivételt okozhat.

A Close() metódus bármilyen állapotban meghívható. Megpróbálja rendesen bezárni az objektumot. Hiba esetén leállítja az objektumot. A metódus nem tesz semmit, ha az aktuális állapot záró vagy lezárt. Ellenkező esetben az állapotot Záró értékre állítja. Ha az eredeti állapot létre lett hozva, megnyitás vagy hibás, akkor az Abort() meghívását kéri (lásd az alábbi ábrát). Ha az eredeti állapot meg lett nyitva, meghívja az OnClosing() (amely a záró eseményt emeli), az OnClose() és a OnClosed() metódust ebben a sorrendben. Ha ezek közül bármelyik kivételt okoz, a Close()meghívja az Abort() metódust, és lehetővé teszi a kivétel buborékjának felbuborását. Az OnClosed() az állapotot Lezárt értékre állítja, és a Bezárt eseményt állítja be. Az alábbi ábrán részletesebben látható a Bezárás folyamat.

Dataflow diagram of ICommunicationObject.Close state changes.
Felülbírálja az OnClose metódust az egyéni bezárási logika implementálásához, például egy belső kommunikációs objektum bezárásához. Minden olyan kecses záró logikát, amely hosszú ideig blokkolhat (például arra vár, hogy a másik fél válaszoljon) az OnClose() alkalmazásban kell implementálnia, mert időtúllépési paramétert vesz igénybe, és mivel nem az Abort() részeként hívják meg.

Megszakítás

Előfeltétel: Nincs.
Állapot utáni állapot: Az állapot lezárult. Kivételt okozhat.

Az Abort() metódus semmit nem tesz, ha az aktuális állapot lezárva van, vagy ha az objektumot korábban leállították (például ha az Abort() végrehajtása egy másik szálon történik). Ellenkező esetben bezárja az állapotot, és meghívja az OnClosing() függvényt (amely a záróeseményt emeli), az OnAbort() és a OnClosed() metódust ebben a sorrendben (nem hívja meg az OnClose-t, mert az objektum leáll, nem bezárva). Az OnClosed() az állapotot Lezárt értékre állítja, és a Bezárt eseményt állítja be. Ha ezek közül bármelyik kivételt okoz, a rendszer újra bedobja az Abort hívójának. Az OnClosing(), az OnClosed() és az OnAbort() implementációi nem tilthatók le (például bemeneten/kimeneten). Az alábbi ábra részletesebben mutatja be a megszakítási folyamatot.

Dataflow diagram of ICommunicationObject.Abort state changes.
Bírálja felül az OnAbort metódust az egyéni megszakítási logika implementálásához, például egy belső kommunikációs objektum megszüntetéséhez.

Hiba

A hibametódus a felületre jellemző CommunicationObject , és nem része a ICommunicationObject felületnek. A teljesség érdekében itt találja.

Előfeltétel: Nincs.

Állapot utáni állapot: Az állapot hibás. Kivételt okozhat.

A Fault() metódus nem tesz semmit, ha az aktuális állapot hibás vagy lezárt. Ellenkező esetben a hibás állapotot állítja be, és meghívja az OnFaulted() parancsot, amely a hibás eseményt indítja el. Ha az OnFaulted kivételt jelez, az újra lesz dobva.

ThrowIfXxx metódusok

A CommunicationObject három védett metódussal rendelkezik, amelyekkel kivételeket vethet ki, ha az objektum egy adott állapotban van.

ThrowIfDisposed kivételt eredményez, ha az állapot záró, lezárt vagy hibás.

ThrowIfDisposedOrImmutable kivételt eredményez, ha az állapot nincs létrehozva.

ThrowIfDisposedOrNotOpen kivételt eredményez, ha az állapot nincs megnyitva.

A kidobott kivételek az állapottól függenek. Az alábbi táblázat a különböző állapotokat és a megfelelő kivételtípust mutatja be az adott állapotra dobó ThrowIfXxx meghívásával.

Állapot Megszakadt a hívás? Kivétel
Létrehozva n/a System.InvalidOperationException
Megnyitás n/a System.InvalidOperationException
Megnyitva n/a System.InvalidOperationException
Lezárás Igen System.ServiceModel.CommunicationObjectAbortedException
Lezárás Nem System.ObjectDisposedException
Lezárva Igen System.ServiceModel.CommunicationObjectAbortedException abban az esetben, ha egy objektumot az Abort korábbi és explicit hívása zárt be. Ha az objektumon a Bezárás parancsot hívja meg, akkor a függvény egy System.ObjectDisposedException műveletet indít el.
Lezárva Nem System.ObjectDisposedException
Hibás n/a System.ServiceModel.CommunicationObjectFaultedException

Időtúllépések

Az általunk tárgyalt módszerek közül számos időtúllépési paramétereket vesz igénybe. Ezek a Bezárás, a Megnyitás (bizonyos túlterhelések és aszinkron verziók), az OnClose és az OnOpen. Ezeket a módszereket úgy tervezték, hogy lehetővé tegyék a hosszadalmas műveleteket (például blokkolja a bemenetet/kimenetet, miközben kecsesen bezár egy kapcsolatot), így az időtúllépési paraméter jelzi, hogy az ilyen műveletek mennyi ideig tarthatnak a megszakítás előtt. Ezeknek a módszereknek a implementációinak a megadott időtúllépési értéket kell használniuk annak biztosítására, hogy az adott időtúllépésen belül visszatérjen a hívóhoz. Az időtúllépést nem igénylő egyéb módszerek implementációi nem hosszú műveletekre vannak tervezve, és nem tilthatják le a bemenetet/kimenetet.

Kivételt képeznek az Open() és Close() túlterhelések, amelyek nem vesznek igénybe időtúllépést. Ezek a származtatott osztály által megadott alapértelmezett időtúllépési értéket használják. CommunicationObject két védett absztrakt tulajdonságot tesz elérhetővé, amelyek neve DefaultCloseTimeout és DefaultOpenTimeout definíciója a következő:

protected abstract TimeSpan DefaultCloseTimeout { get; }

protected abstract TimeSpan DefaultOpenTimeout { get; }

A származtatott osztály implementálja ezeket a tulajdonságokat, hogy megadja az alapértelmezett időtúllépést az open() és close() túlterhelésekhez, amelyek nem vesznek igénybe időtúllépési értéket. Ezután az Open() és Close() implementációk delegálják a túlterhelést, amely időtúllépést vesz igénybe, és az alapértelmezett időtúllépési értéket adja át, például:

public void Open()

{

this.Open(this.DefaultOpenTimeout);

}

IDefaultCommunicationTimeouts

Ez a felület négy írásvédett tulajdonsággal rendelkezik, amelyek alapértelmezett időtúllépési értékeket biztosítanak a megnyitáshoz, küldéshez, fogadáshoz és bezáráshoz. Minden implementáció felelős azért, hogy az alapértelmezett értékeket a megfelelő módon szerezze be. Kényelmes ChannelFactoryBase , és ChannelListenerBase alapértelmezés szerint ezek az értékek egyenként 1 percet tartalmaznak.