Showing posts with label task. Show all posts
Showing posts with label task. Show all posts

Friday, May 27, 2016

Asinhrono, async i await višenitno programiranje

Dolaskom C# programskog jezika verzije 5, u C# programski jezik su uključene dve nove ključne reči async i await, dve komande koje ne idu jedna bez druge. Laički rečeno, tamo gde vidite da je metoda definisana sa async, u toj metodi trebate imati i ključnu reč await. Njihova magija je u tome što one omogućavaju višenitno programiranje ali bez direktnog formiranja niti. Sve do pojave asinhronog programiranja, svi vaši .Net programi bez dodatnog programiranja su sve operacije izvršavale sekvencijalno. To u prevodu znači da su se operacije izvršavale jedna po jedna i svaka operacija je morala čekati da se svaka prethodna operacija izvrši do kraja. Kad god napravite aplikaciju poput Windows Form, ona poseduje samo jednu nit; Main thread – glavnu ili UI nit; i sad zamislite da u toj niti koristite I/O operaciju. Vaš Windows će tada čekati dok vi pristupate nekom fajlu na hard disku ili mreži dok god se vaša operacija ne izvrši do kraja. Zbog toga Windows pauzira vašu nit tako da on ne koristi ni jedan CPU resurs ali na taj način zadržava memoriju.


( Asinhronizovano programiranje )

Asinhrono programiranje je jednostavno rešilo ovaj problem, jer asinhrono programiranje za razliku od sekvencijalnog ili sinhronog programiranja vam omogućava da vi pokrenete neku metodu i nastavljate da radite neki drugi posao dok se metoda ne završi. Inače sa sinhronim programiranjem pokrećete neku metodu; morate da čekate da se metoda izvrši do kraja; prosledi vam se neki rezultat i onda se nastavlja vaše izvršavanje programa. Danas se u programiranju koristi i jedna i druga varijanta u zavisnosti da li radite sa I/O operacijama ili jednostavno vam je potrebno više vremena da se izvrši neka metoda. Danas celi koncept Funkcionalnog programiranja je daleko bolji kad se radi preko asinhronizovani delegata, dok na primer UWP ili Phone aplikacija bez asinhroni metoda je nezamisliva jer svaka metoda koja radi duže od 2 sekunde je neprihvatljiva. Asinhrono programiranje se koristi kad imate kompleksne upite koje uzimaju dosta vremena, šaljete email-ove ili radite sa fajlovima. Nadam se da vam je sad jasno koliko je asinhrono programiranje bitno, ali takođe treba da znate da asinhronizovano programiranje nije lako jer se vi morate pobrinuti da ništa ne krene pogrešno, takođe je komplikovano debugovanje i održavanje istog. Ključnu reč async koristite da markirate metodu za asinhronizovanu operaciju. Na taj način vi samo dajete signal vašem kompajleru da će se nešto asinhronizovano desiti. Kompajler tada transformiše vašu kod u programersku C# paradigmu koju zovemo state machine. Znači pokreće sinhronično trenutnu nit, ali vam omogućava da vašu metodu razdvojite u više delova. Kad koristite await ključnu reč, kompajler će generisati kod koji će te videti bez obzira da li je vaša asinhronizovana operacija završena. Ako se vaša metoda samo sinhronizovano nastavlja, u prevodu nije završena; onda će state machine spojiti sa kontinuiranom metodom koja će se pokrenuti kada se task završi. Prepustiće kontrolu pozivajućoj niti i ta nit će se moći koristiti za drugi posao. Imajte u vidu da asinhronizovana metoda može da vrati rezultat samo kao void, Task i Task<T>.

Kako izgleda neki praktični primer asinhronog programiranja?


Wednesday, May 04, 2016

Rad sa taskovima u C# programskom jeziku


U prethodnom postu „Rad sa nitima u C# programskom jeziku“ je u najkraćim crtama sa čak 7 primera objašnjeno kako se radi sa nitima. Međutim, da bi ste razumeli niti i to je malo. Na internetu možete pronaći mnogo primera varijacija i upotrebe niti, dok možete i trebate eksperimentisati i sa vlastitim kombinacijama. Zato vam savetujem da mnogo samostalno eksperimentišete i testirate vaše vlastite metode pozivajući ih u nitima; u vašim vlastitim testovima i aplikacijama. To se isto odnosi i na taskove i na asinhronizovane metode i sve što učite. Takođe, morate da poznajete razliku i kad i šta treba da koristite. Na primer, pored upotrebe niti će te brzo shvatili da je mnogo bolje koristiti klasu ThreadPool nego klasu Threading pogotovo ako nameravate koristiti više niti sa dugotrajnim procesima ili kad više puta nameravate koristiti istu nit. Razlog je jednostavan, niti su expensive – skupi. Znači uzimaju mnogo memorije i vremena. Potrebno vam je 1MB za svaku nit koju koristite. Klasa Threading vam omogućava da kreirate niti na veoma niskom nivou, na nivou OS – Operativnog sistema. To znači da nad niti imate punu kontrolu, tj. možete da nit pokrenete, zaustavite ili prekinete.

 
( Taskovi su često mnogo bolje rešenje od upotrebe niti ) 

Za razliku od niti ThreadPool je delimično rešenje jer je mnogo jeftiniji; upamtite i da u ThreadPool-u svaka nit je uvek Background nit i da se niti u ThreadPool ne uništavaju kad se nit izvrši. Ali sa ThreadPool-om vi ne možete određivati prioritete izvršavanja niti, zato bi ste morali koristiti neke druge mehanizme; isto tako vi ne možete niti prekinuti u vreme izvršavanja. Kada koristite ThreadPool nemate kontrolu nad nitima kao sa klasom Threading jer ThreadPool radi na nivou CLR – Common Language Runtime-a. To znači i da broj niti koji možete izvršavati u ThreadPool-u zavisi od verzije .Net Framework-a kojeg koristite. Na primer ako koristite .NET Framework 4.0 onda možete koristiti 1 023 niti za 32-bit aplikacije ili 32 767 za 64-bit aplikacije. Međutim ako koristite .Net Framework 2.0 ograničeni ste na samo 25 niti prema procesoru. Isto tako vi faktički, najjednostavnije rečeno; samo pošaljete vaše zadatke u ThreadPool, kad se ThreadPool napuni vi samo trebate sačekati dok se ne oslobodi i nastavi sa izvršavanjem drugih zadataka. Vi čak možete i sami da odredite veličinu ThreadPool-a ali činjenica je da kontrolu nemate. Vi možete da pošaljete neki zadatak, ali ne možete sačekati da se završi ili da prihvatite neki rezultat. Zato postoji klasa Task koja rešava probleme i nedostatke i klase Threading i klase ThreadPool.

Kako da kreiramo taskove?