HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Szálak menedzselése C#-ban


Példaprogram letöltése

8782 bájt

Alkalmazásainkban nagyon gyakran kell használnunk a többszálas technológiát, vagyis bizonyos időigényes folyamatokat a főszáltól eltérő szál segítségével kell végrehajtanunk, hogy a főszál terhelése csökkenjen. Ennek megoldására a .NET beépített lehetőségeket kínál. Speciális osztályai segítségével egy menedzselt listában helyezhetjük el a folyamatokat végző elindított szálakat, melyekről a továbbiakban a futtatórendszer gondoskodik. Cikkünkben ennek megvalósítására mutatunk egy példát.

Szálmenedzselés (thread pooling)
A .NET Framework segítségével lehetőségünk van hatékonyabb több szálon futó alkalmazást írni. Számtalan alkalmazás használja a többszálas technológiát, azonban a legtöbb esetben egy-egy szál nagyon sok időt tölt várakozással egy adott eseményre.
A .NET rendszerben egy olyan komplex szálmenedzselő algoritmust kapunk készen, mely egy csokorba gyűjti az adott process WORKER szálait úgy, hogy a szálak közt a lehető legoptimálisabban osztja el a processzoridőt. Ennek eredményeképpen a fejlesztő koncentrálhat az alkalmazás logikájára ahelyett, hogy a szálak menedzselésével kellene törődnie.
Olyan esetekben tehát, ahol több rövid, de külön szálat igénylő feladatot kell megoldanunk, használhatjuk a ThreadPool osztály lehetőségeit, így a többszálú programozás minden előnye rendelkezésünkre áll.
A beépített szálmenedzser lehetővé teszi, hogy a rendszer optimalizálja a szálak tevékenységét a lehető legnagyobb eredmény elérése érdekében az adott process esetében, továbbá a számítógép egyéb, a szálakkal kapcsolatban álló egyéb process-ek esetében egyaránt. Mindezekről az alkalmazás természetesen mit sem sejt.
A .NET szálmenedzselő rendszere a következő esetekben használható igen jól:
  • Aszinkron hívások esetében
  • Socket kommunikációt használó kód esetén
  • Aszinkron I/O tevékenység esetén
Menedzselt kód esetén a ThreadPool.QueueUserWorkItem statikus metódus meghívásával adhatunk egy adott szálat a gyűjteménybe, és a WaitOrTimerCallback delegált segítségével adhatjuk át annak a metódusnak a címét, melyet az adott szál végrehajt.
Egy alkalmazás domain egy ThreadPool objektumot tartalmaz, mely akkor jön létre, amikor első alkalommal hívódik meg a ThreadPool.QueueUserWorkItem metódus. Amikor egy task befejeződik, akkor meghívja a megfelelő CALLBACK metódust. A működési elvhez az is hozzátartozik, hogy miután egy szál besorolásra került a menedzselt kollekcióba, azt onnan eltávolítani nem lehet.
A menedzselt kollekcióba felvehető szálak számát csak a PC-ben rendelkezésre álló memória szabja meg, ugyanakkor az algoritmus megszab egy bizonyos maximális szálszámot, melynél még biztonságosan üzemeltethető a szálak szimultán futtatása.
Minden szál az alapértelmezett vermet használja, az alapértelmezett prioritással fut, és a többszálas apartment-ban található (MTA). Abban az esetben, ha a sorban található valamennyi szál foglalt, de van még függőben levő elvégzendő feladat, a szálmenedzselő algoritmus néhány időperiódus után létrehozza a további szükséges munkaszálat.
A szálakkal történő műveletvégzést csak bizonyos speciális esetekben nem ajánlatos a menedzserre bízni. Ezek a következők:
  • A szálakhoz egyedi prioritást szeretnénk beállítani.
  • Van olyan művelet, melynek elvégzése hosszabb időperiódust igényel.
  • Ha a szálat egy single-threaded apartment-ban szeretnénk elhelyezni (STA).
  • Ha stabil azonosítóval kívánjuk ellátni az adott szálat.
Gyakorlati felhasználás
A példánkban a gombra kattintva létrehozhatunk három szálat, melyek bekerülnek a ThreadPool objektum által reprezentált gyűjteménybe, majd minden szálobjektum elkezdi a megadott I/O műveletet úgy, hogy a projekt mappájában megtalálható File.txt állomány 4 sorát kiolvassa egy karakterláncba, majd azt megjelenítse a program ListBox kontroljában.
A gomb lenyomásakor példányosítjuk az AutoResetEvent osztályt, melynek feladata, hogy értesítse az éppen várakozó szálakat arról, hogy egy esemény bekövetkezett. Az objektum addig marad jelző (signaled) állapotban, míg az adott várakozó szál el nem kezdi a műveletet. Ekkor a rendszer automatikusan nem-jelző állapotba állítja az objektumot (nevezhetjük ezt egy szemafornak). Amennyiben nincs várakozó szál, akkor az objektum jelző-állapotban marad.
AutoResetEvent ev = new AutoResetEvent(false);
Ezt a delegáltat a ThreadPool objektum RegisterWaitForSingleObject metódusa segítségével regisztrálhatjuk.
ThreadPool.RegisterWaitForSingleObject(ev, new WaitOrTimerCallback(TimeoutMethod), null, 20000,false);
A metódus második paraméterében kell megadnunk azt a CALLBACK metódust, mely akkor kerül meghívásra, amikor a negyedik paraméterben megadott idő (timeout) lejár, vagy ha a fent deklarált objektum jelzett állapotba kerül.
A példánkban meghíváskor beírunk egy sort a ListBox kontrolba.
if (signaled)
{
  listBox1.Items.Add("TimeoutMethod .....");      
}
A szálak a QueueUserWorkItem metódussal kerülnek a kollekcióba, annak paraméterében megadva a meghívandó metódus nevét.
for(int i=0;i<3;i++)
{
  ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), i);        
  ev.Set();
  Thread.Sleep(1000);
}
A metódusban az adott hívó szál a menedzser-algoritmus által meghatározott módon kiolvassa az állomány soron következő sorát, majd beírja azt a ListBox kontrolba, feltüntetve az éppen olvasó szálat.
StreamReader reader = new StreamReader("file.txt");      
string line = "";
switch(o.ToString())
{
  case "0":  
    for(int i=0;i<4;i++){
      line = reader.ReadLine();
      listBox1.Items.Add("Első szál -> " + line);
      Thread.Sleep(2000);
    }
    listBox1.Items.Add("Első szál bent a sorban ...");  
    break;
    ...
A program futásakor megfigyelhető, hogy a szálaknak a menedzser-algoritmus osztja a processzoridőt, így azok periodikusan váltakozva olvasnak egy-egy sort az állományból.

Cikksorozat

#IDKategóriaCikk címeSorozat
2591WindowsTippek és trükkök - RAS - Modem csengetési szám állítása1. rész
2622WindowsTippek és trükkök - Program futtatása más felhasználóként2. rész
2640WindowsA Windows ikonméretének megváltoztatása és Windows 2000 Asztaltémák3. rész
2657WindowsTippek és trükkök - Internet Explorer4. rész
2667WindowsTippek és trükkök5. rész
2684WindowsAlapértelmezések állítása, telepítési fájlok helye, intéző nézetek6. rész
2696WindowsBiztonsági trükkök7. rész
2702WindowsWindows XP trükkök8. rész
2729WindowsWindows 2000 és XP tippek, trükkök9. rész
2757WindowsRegistry trükkök10. rész
2784WindowsTippek, trükkök11. rész
2829WindowsTippek, trükkök12. rész
2889WindowsWindows XP tippek13. rész
2909WindowsTippek Windows XP-hez14. rész
2919WindowsWindows tippek15. rész
2924WindowsWindows tippek16. rész
2963WindowsWindows tippek17. rész
2973WindowsWindows Tippek18. rész
2981WindowsWindows tippek19. rész
2990WindowsTippek-trükkök20. rész
3027WindowsIIS tippek21. rész
3034WindowsWindows XP tippek-trükkök22. rész
3088WindowsWindows 2000/XP tippek, trükkök23. rész
3133WindowsWindows XP tippcsokor24. rész
3140WindowsWindows XP tippek, trükkök25. rész
3152WindowsXP és IIS tippek - trükkök26. rész
3158WindowsWindows XP tippek, trükkök27. rész
3168WindowsTippek, trükkök28. rész
3170WindowsRegistry trükkök29. rész
3179WindowsTippek, trükkök30. rész
3197WindowsWindows XP tippek, trükkök31. rész
3205WindowsTippek, trükkök32. rész
3214WindowsTippek, trükkök33. rész
3223WindowsTippek, trükkök34. rész
3233WindowsTippek, trükkök35. rész
3271WindowsTippek, trükkök36. rész
3307WindowsTippek, trükkök37. rész
3370WindowsTippek, trükkök38. rész
3399WindowsTippek, trükkök39. rész
3510WindowsTippek, trükkök40. rész
3611WindowsHardverrel kapcsolatos tippek, trükkök41. rész
3668WindowsRegistry trükkök42. rész
3711WindowsTippek, trükkök43. rész
3771WindowsTippek, trükkök44. rész
3801WindowsTippek, trükkök45. rész
3831WindowsTippek, trükkök46. rész
3891WindowsTippek, trükkök47. rész
3921WindowsTippek, trükkök48. rész
3981WindowsTippek, trükkök49. rész
4041WindowsTippek, trükkök50. rész
4071WindowsTippek, trükkök51. rész
4151WindowsTippek, trükkök52. rész
4171C#Tippek, trükkök53. rész
4211WindowsTippek, trükkök54. rész
4251WindowsTippek, trükkök55. rész
4281WindowsTippek, trükkök56. rész
3589DelphiTippek, trükkök57. rész
3718DelphiTippek, trükkök58. rész


Könyv
Ez a cikk megtalálható ebben a könyvben: C# Software Offline 2003 évkönyv 517. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |