Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
Az inicializálási minta egy interfész definiálásával kibővíti a készletezési mintát, IObjectControlamely aktiválással és inaktiválással testre szabja egy objektum inicializálását. Az ügyfél olyan metódusokat hív meg, amelyek visszaadják az objektumot a készletnek, és amelyek nem a készletnek adják vissza az objektumot.
Feljegyzés
A minta telepítési eljárása és összeállítási utasításai a témakör végén találhatók.
Bővíthetőségi pontok
A Windows Communication Foundation (WCF) bővítmény létrehozásának első lépése a használni kívánt bővíthetőségi pont kiválasztása. A WCF-ben az EndpointDispatcher kifejezés egy futtatókörnyezeti összetevőre utal, amely felelős a bejövő üzenetek metódushívásokká alakításáért a felhasználó szolgáltatásában, valamint a visszatérési értékeknek a metódusból kimenő üzenetté alakításáért. A WCF-szolgáltatás minden végponthoz létrehoz egy EndpointDispatchert.
Az EndpointDispatcher a végpont hatókörét (a szolgáltatás által fogadott vagy küldött összes üzenethez) bővíti az EndpointDispatcher osztály használatával. Ez az osztály lehetővé teszi az EndpointDispatcher viselkedését vezérlő különböző tulajdonságok testreszabását. Ez a minta a InstanceProvider szolgáltatásosztály példányait biztosító objektumra mutató tulajdonságra összpontosít.
IInstanceProvider
A WCF-ben az EndpointDispatcher egy szolgáltatásosztály példányait hozza létre egy olyan példányszolgáltató használatával, amely implementálja az interfészt IInstanceProvider . Ennek a felületnek csak két módszere van:
GetInstance: Amikor egy üzenet megérkezik, a diszpécser meghívja a metódust, GetInstance hogy hozzon létre egy példányt a szolgáltatásosztályból az üzenet feldolgozásához. A metódus hívásainak gyakoriságát a InstanceContextMode tulajdonság határozza meg. Ha például a InstanceContextMode tulajdonság értéke be van állítva InstanceContextMode.PerCall, a rendszer létrehoz egy új szolgáltatásosztály-példányt az egyes érkező üzenetek feldolgozásához, így GetInstance az üzenet érkezésekor is ezt nevezzük.
ReleaseInstance: Amikor a szolgáltatáspéldány befejezi az üzenet feldolgozását, az EndpointDispatcher meghívja a metódust ReleaseInstance . A metódushoz GetInstance hasonlóan a metódus hívásainak gyakoriságát a InstanceContextMode tulajdonság határozza meg.
Az objektumkészlet
Az ObjectPoolInstanceProvider osztály tartalmazza az objektumkészlet implementációját. Ez az osztály implementálja az interfészt a IInstanceProvider szolgáltatásmodell-réteggel való interakcióhoz. Amikor az EndpointDispatcher meghívja a GetInstance metódust, ahelyett, hogy új példányt hoz létre, az egyéni implementáció egy meglévő objektumot keres egy memórián belüli készletben. Ha elérhető, a függvény visszaadja. Ellenkező esetben ellenőrizze, ObjectPoolInstanceProvider hogy a tulajdonság (a ActiveObjectsCount készletből visszaadott objektumok száma) elérte-e a készlet maximális méretét. Ha nem, a rendszer létrehoz egy új példányt, és visszaadja a hívónak, és ActiveObjectsCount ezt követően megnövekedik. Ellenkező esetben az objektumlétrehozási kérések egy konfigurált időszakra lesznek várólistára állítva. A megvalósítás a GetObjectFromThePool következő mintakódban látható.
private object GetObjectFromThePool()
{
bool didNotTimeout =
availableCount.WaitOne(creationTimeout, true);
if(didNotTimeout)
{
object obj = null;
lock (poolLock)
{
if (pool.Count != 0)
{
obj = pool.Pop();
activeObjectsCount++;
}
else if (pool.Count == 0)
{
if (activeObjectsCount < maxPoolSize)
{
obj = CreateNewPoolObject();
activeObjectsCount++;
#if (DEBUG)
WritePoolMessage(
ResourceHelper.GetString("MsgNewObject"));
#endif
}
}
idleTimer.Stop();
}
// Call the Activate method if possible.
if (obj is IObjectControl)
{
((IObjectControl)obj).Activate();
}
return obj;
}
throw new TimeoutException(
ResourceHelper.GetString("ExObjectCreationTimeout"));
}
Az egyéni ReleaseInstance implementáció hozzáadja a felszabadított példányt a készlethez, és lecsökkenti az ActiveObjectsCount értéket. Az EndpointDispatcher különböző szálakból hívhatja meg ezeket a metódusokat, ezért szinkronizált hozzáférésre van szükség az ObjectPoolInstanceProvider osztály osztályszintű tagjaihoz.
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
lock (poolLock)
{
// Check whether the object can be pooled.
// Call the Deactivate method if possible.
if (instance is IObjectControl)
{
IObjectControl objectControl = (IObjectControl)instance;
objectControl.Deactivate();
if (objectControl.CanBePooled)
{
pool.Push(instance);
#if(DEBUG)
WritePoolMessage(
ResourceHelper.GetString("MsgObjectPooled"));
#endif
}
else
{
#if(DEBUG)
WritePoolMessage(
ResourceHelper.GetString("MsgObjectWasNotPooled"));
#endif
}
}
else
{
pool.Push(instance);
#if(DEBUG)
WritePoolMessage(
ResourceHelper.GetString("MsgObjectPooled"));
#endif
}
activeObjectsCount--;
if (activeObjectsCount == 0)
{
idleTimer.Start();
}
}
availableCount.Release(1);
}
A ReleaseInstance metódus egy tisztítási inicializálási funkciót biztosít. A készlet általában minimális számú objektumot tart fenn a készlet élettartamára vonatkozóan. Előfordulhat azonban, hogy a túlzott használat miatt további objektumokat kell létrehozni a készletben, hogy elérjék a konfigurációban megadott maximális korlátot. Végül, amikor a készlet kevésbé aktív lesz, ezek a felesleges objektumok többletterhelést jelenthetnek. Ezért amikor a activeObjectsCount nullát eléri, elindul egy tétlen időzítő, amely elindítja és elvégzi a tisztítási ciklust.
if (activeObjectsCount == 0)
{
idleTimer.Start();
}
A ServiceModel-rétegbővítmények a következő viselkedéssel vannak összekapcsolva:
Szolgáltatás viselkedése: Ezek lehetővé teszik a teljes szolgáltatás-futtatókörnyezet testreszabását.
Végponti viselkedések: Ezek lehetővé teszik egy adott szolgáltatásvégpont testreszabását, beleértve az EndpointDispatchert is.
Szerződési viselkedések: Ezek lehetővé teszik az ügyfél vagy ClientRuntime a szolgáltatás vagy osztályok testreszabásátDispatchRuntime.
Műveleti viselkedések: Ezek lehetővé teszik az ügyfél vagy ClientOperation a szolgáltatás vagy az osztályok testreszabásátDispatchOperation.
Objektumkészletezési bővítmény céljából végponti vagy szolgáltatásviselkedés hozható létre. Ebben a példában egy szolgáltatás viselkedését használjuk, amely a szolgáltatás minden végpontjára alkalmazza az objektumkészletezési képességet. A szolgáltatás viselkedése a IServiceBehavior felület implementálásával jön létre. A ServiceModel többféleképpen is tudatható az egyéni viselkedésekkel:
Egyéni attribútum használata.
Feltétlenül adja hozzá a szolgáltatásleírás viselkedésgyűjteményéhez.
A konfigurációs fájl kiterjesztése.
Ez a minta egy egyéni attribútumot használ. A ServiceHost létrehozásakor megvizsgálja a szolgáltatás típusdefiníciójában használt attribútumokat, és hozzáadja az elérhető viselkedéseket a szolgáltatásleírás viselkedésgyűjteményéhez.
Az IServiceBehavior interfésznek három módszere van: Validate,AddBindingParameters, és.ApplyDispatchBehavior Ezeket a metódusokat a WCF hívja meg az ServiceHost inicializáláskor.
IServiceBehavior.Validate az első; lehetővé teszi a szolgáltatás számára az inkonzisztenciák vizsgálatát.
IServiceBehavior.AddBindingParameters a következőnek hívják; ez a módszer csak nagyon speciális helyzetekben szükséges.
IServiceBehavior.ApplyDispatchBehavior az utolsó hívás, és felelős a futtatókörnyezet konfigurálásáért. A rendszer a következő paramétereket adja át IServiceBehavior.ApplyDispatchBehavior:
Description: Ez a paraméter a teljes szolgáltatás szolgáltatásleírását tartalmazza. Ez a szolgáltatás végpontjaival, szerződéseivel, kötéseivel és a szolgáltatáshoz társított egyéb adatok leírási adatainak vizsgálatára használható.ServiceHostBase: Ez a paraméter az ServiceHostBase inicializálás alatt álló paramétert adja meg.
Az egyéni IServiceBehavior implementációban a rendszer létrehoz egy új példányt ObjectPoolInstanceProvider , amely a InstanceProvider tulajdonsághoz EndpointDispatcher van ServiceHostBaserendelve.
public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
{
if (enabled)
{
// Create an instance of the ObjectPoolInstanceProvider.
instanceProvider = new ObjectPoolInstanceProvider(description.ServiceType,
maxPoolSize, minPoolSize, creationTimeout);
// Assign our instance provider to Dispatch behavior in each
// endpoint.
foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher cd = cdb as ChannelDispatcher;
if (cd != null)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider = instanceProvider;
}
}
}
}
}
A megvalósítás mellett IServiceBehavior az ObjectPoolingAttribute osztály több taggal is rendelkezik az objektumkészlet testreszabásához az attribútumargumentumok használatával. Ezek a tagok a .NET Enterprise Services által biztosított objektumkészletezési funkciókészletnek megfelelőt tartalmazzák MaxSizeMinSizeEnabledCreationTimeout.
Az objektumkészletezési viselkedés mostantól hozzáadható egy WCF-szolgáltatáshoz a szolgáltatás implementációjának megjegyzésével az újonnan létrehozott egyéni ObjectPooling attribútummal.
[ObjectPooling(MaxSize=1024, MinSize=10, CreationTimeout=30000]
public class PoolService : IPoolService
{
// …
}
Aktiválás és inaktiválás csatlakoztatása
Az objektumkészletezés elsődleges célja a rövid élettartamú objektumok viszonylag költséges létrehozása és inicializálása. Ezért jelentősen növelheti az alkalmazás teljesítményét, ha megfelelően használják. Mivel az objektumot a rendszer a készletből adja vissza, a konstruktor csak egyszer lesz meghívva. Egyes alkalmazások azonban bizonyos szintű vezérlést igényelnek, hogy inicializálhassák és megtisztíthassák az egyetlen környezetben használt erőforrásokat. A számításokhoz használt objektumok például alaphelyzetbe állíthatják a privát mezőket a következő számítás feldolgozása előtt. Az Enterprise Services ezt a környezetspecifikus inicializálást úgy engedélyezte, hogy az objektumfejlesztő felülbírálja Activate a Deactivate metódusokat az ServicedComponent alaposztályból.
Az objektumkészlet meghívja a metódust Activate , mielőtt visszaadja az objektumot a készletből.
Deactivate akkor lesz meghívva, amikor az objektum visszakerül a készletbe. Az ServicedComponent alaposztálynak van egy boolean nevű tulajdonsága CanBePooledis, amellyel értesítheti a készletet, hogy az objektum tovább készletezhető-e.
A funkció utánzásához a minta egy nyilvános felületet (IObjectControl) deklarál, amely rendelkezik a fent említett tagokkal. Ezt a felületet ezután a szolgáltatásosztályok implementálják, amelyek környezetspecifikus inicializálást biztosítanak. A IInstanceProvider megvalósítást módosítani kell, hogy megfeleljen ezeknek a követelményeknek. Most, minden alkalommal, amikor egy objektumot kap a GetInstance metódus meghívásával, ellenőriznie kell, hogy az objektum megvalósítja-e IObjectControl. , ha igen, megfelelően kell meghívnia a Activate metódust.
if (obj is IObjectControl)
{
((IObjectControl)obj).Activate();
}
Amikor egy objektumot ad vissza a készlethez, ellenőrizni kell a CanBePooled tulajdonságot, mielőtt hozzáadja az objektumot a készlethez.
if (instance is IObjectControl)
{
IObjectControl objectControl = (IObjectControl)instance;
objectControl.Deactivate();
if (objectControl.CanBePooled)
{
pool.Push(instance);
}
}
Mivel a szolgáltatásfejlesztő eldöntheti, hogy egy objektum készletezhető-e, a készletben lévő objektumok száma egy adott időpontban a minimális méret alá csökkenhet. Ezért ellenőriznie kell, hogy az objektumszám a minimális szint alá csökkent-e, és a tisztítási eljárás során végre kell hajtania a szükséges inicializálást.
// Remove the surplus objects.
if (pool.Count > minPoolSize)
{
// Clean the surplus objects.
}
else if (pool.Count < minPoolSize)
{
// Reinitialize the missing objects.
while(pool.Count != minPoolSize)
{
pool.Push(CreateNewPoolObject());
}
}
A minta futtatásakor a műveleti kérelmek és a válaszok megjelennek a szolgáltatás és az ügyfélkonzol ablakaiban is. A szolgáltatás és az ügyfél leállításához nyomja le az Enter billentyűt az egyes konzolablakokban.
A minta beállítása, összeállítása és futtatása
Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták egyszeri beállítási eljárását.
A megoldás létrehozásához kövesse a Windows Communication Foundation-minták készítésére vonatkozó utasításokat.
Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse a Windows Communication Foundation-minták futtatásával kapcsolatos utasításokat.