WF és ASP.NET: threading

A Workflow Foundation runtime alapértelmezés szerint aszinkron módon futtatja az egyes workflow példányokat, azaz minden egyes új példány létrehozásakor kér egy szabad szálat a CLR ThreadPooltól és azon indítja el a workflow-t alkotó activity-k futtatását.

A november végi MSDN konferencián röviden volt szó arról, hogy ez az aszinkron viselkedés néha gondot jelent, például webes környezetben. Az ASP.NET ugyanis maga gondoskodik az egyes kérésekhez érkező szálak kezeléséről és az újabb szálak indítása csak rontana a helyzeten. Arról nem is beszélve, hogy az aszinron végrehajtást nehéz egy oldal rendereléséhez igazítani.

A megoldás az ütemezésért felelős ManualWorkflowSchedulerService hozzáadása a runtime-hoz:

WorkflowRuntime runtime = new WorkflowRuntime();
ManualWorkflowSchedulerService scheduler = new ManualWorkflowSchedulerService();
runtime.AddService( scheduler );

Na ennyivel még nem vagyunk készen. Mivel a ManualWorkflowSchedulerService nem a ThreadPooltól kér szálat, ezért nekünk kell adnunk egyet, amin szinkron módon tudja futtatni a workflow-t, például valahogy így:

WorkflowInstance instance = runtime.CreateWorkflow( typeof( MyWorkflow ) );
instance.Start();
scheduler.RunWorkflow( instance.InstanceId );

A RunWorkflow metódusról ezt írja az MSDN:

This is a synchronous call that uses the current thread to run the workflow. It does not return until the workflow idles, suspends, completes, terminates, or aborts.

Magyarul a RunWorkflow() belerúg egyet a folyamatba és akkor tér vissza, amikor az megáll (befejeződik, várakozik, hibázik stb.). Ez sok esetben nem is rossz, de képzeljük el a következő szituációt: timeout-tal szeretnénk várakozni egy eseményre. Szépen behajítjuk a folyamatba a HandleExternalEvent és a Delay activity-ket, gyönyörűen párhuzamosítva egymással egy Listen activity-n belül. Meghívjuk a RunWorkflow()-t, ami futtatja a folyamatot egészen az eseményre várakozásig, ahogy az a nagy könyvben meg van írva. Ámde a várva várt esemény nem jön. Ekkor kellene kattannia a timeout-ot jelző Delay activity-nek.

Csakhogy nincs hol kattanjon. Nincs min kattanjon. Nincs mikor kattanjon. A workflow példányunk ugyanis egész egyszerűen nem fut. Executing állapotban van, de valójában nem fut. Egy szinkron módon futtatott workflow példány csak akkor fut, ha adunk szálat alá.

Ugyanez a probléma akkor is, ha eseménnyel üzenünk a workflow példánynak. Az esemény szépen beáll a "workflow számára továbbítandó események sorába", de majd csak akkor fog lefutni a workflow definícióban hozzá tartozó eseménykezelő, ha meghívjuk a RunWorkflow() metódust. Nem elég, hogy macerás a kommunikáció, még a folyamat továbbléptetéséről is nekünk kell gondoskodni!

Képzeljük el mindezt egy webalkalmazásban! Ha csak nem hívogatjuk passzióból a RunWorkflow() metódust időnként, nem fognak továbbfutni a workflow példányaink. Márpedig egy webalkalmazásban elég körülményes bármit is megcsinálni "időnként".

Advertisements

3 thoughts on “WF és ASP.NET: threading

  1. Unknown

    Szia,
    Akkor most mi is a helyzet???  :)Egy hete tanulom ez a "csodabogarat" és tetszik. Akkor most bugos ez a cucc? Éles alkalmazásban merjem használni?
    Ez mit jelent valójában?
    "az aszinkron
    viselkedés néha gondot jelent, például webes környezetben. Az ASP.NET
    ugyanis maga gondoskodik az egyes kérésekhez érkező szálak kezeléséről
    és az újabb szálak indítása csak rontana a helyzeten. Arról nem is
    beszélve, hogy az aszinron végrehajtást nehéz egy oldal rendereléséhez
    igazítani."Most nézem a videókat, még nem tartok ott, így gondolom emiatt nem értem, hogy milyen hibák keletkeznek. Most egyik megoldás sem jó? Az általad írt megközelítés, mint jelzed az sem működik tökéletesen?
    Csak az asp.net rész érint engem, de mint látom az a zűrösebb. Találok erről részletes leírást a neten valahol?
    Persze fő gondom az, hogy az alap problémát sem értem még…
    Bocsi a kérdésözönért, de most megdöbbentem!
    Na mindegy, de ha esetleg írsz erre a sok kérdésre akkor előre is köszi, és gratulálok a bloghoz, örömmel olvasom, sok hasznos infót tartalmaz.
    üdv,
    sosenk

  2. György

    Szia sosenk!
     
    Nem azt állítom, hogy bugos a termék, csak azt, hogy 1.0-ás 🙂
    Ha az ASP.NET-tel akarod a WF-et összeházasítani, akkor az a probléma, hogy mindkettő maga szeretné kezelni a szálakat, így csak rontanák egymás működését, ezért a WF-ben ezt ki lehet kapcsolni azzal, hogy a ManualWorkflowSchedulert használod. Úgy gondolom, hogy bár lehetséges, nem célszerű ASP.NET-ben közvetlenül használni a WF-t, ehelyett inkább egy webszolgáltatást vagy inkább egy Windows service-t célszerű készíteni, ami folyamatosan futhat a háttérben és az ASP.NET csak kommunikál vele, mint külső komponenssel.
     
    Remélem ez segít.
     
    üdv,
    Balássy György

  3. Unknown

    Hali,Köszi szépen a választ. "Tanulmányaim során" én is erre a következtetésre jutottam, hogy valszeg ezt nem a közvetlen programozásra találták ki, hanem ahogy írtad inkább az alkalmazás-folyamat vezérlő szerepre. A közvetlen használat során szeintem hamar beleunnánk…(Csak megtévesztettek a neten található példák, melyek jó része a közvetlen ASP.NET-ben való használatáról szól.)Ez a webservice-es megoldás lesz a nyerő, főleg ha belegondolunk a WCF-el való használatára…Megdöbbentő. Lehet csak a túlzott optimista beszél belőlem, de szerintem van/lesz akkora előrelépés ismét a 3 és a 3.5-ös verziókkal, mint a 1 és a 2-es verzió között volt.De inkább nagyobb…üdv,sosenk

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s