Programovanie

V metódach Task.Factory.StartNew a Task.Run

Pri vytváraní úloh pomocou metód Task.Factory.StartNew alebo Task.Run by ste mali pri písaní asynchrónneho kódu pamätať na niektoré dôležité body. Vo väčšine prípadov sa odporúča vyhnúť sa použitiu metódy Task.Factory.StartNew, ak pracujete s asynchrónnym kódom. Ak pracujete s paralelným kódom, povedal by som, že StartNew je dobrá voľba.

Plánovač úloh je komponent, ktorý je zodpovedný za plánovanie úloh; Rámec .Net vám poskytuje dva plánovače úloh. Existuje predvolený plánovač úloh, ktorý je spustený vo fonde vlákien .Net framework, a existuje plánovač úloh, ktorý sa vykonáva v kontexte synchronizácie zadaného cieľa. Predvolený plánovač úloh bude väčšinu času stačiť, ale môžete si tiež vytvoriť svoj vlastný vlastný plánovač úloh, ktorý vám poskytne ďalšie funkcie. Ak chcete vytvoriť svoj vlastný plánovač úloh, budete musieť vytvoriť triedu, ktorá rozširuje triedu System.Threading.Tasks.TaskScheduler.

Ako môžem vytvoriť úlohy pomocou paralelnej knižnice úloh?

Existuje niekoľko spôsobov, ako môžete vytvárať a spúšťať úlohy v .Net. Na vytváranie úloh (rozvrhnuteľná pracovná jednotka) musíte využiť triedu System.Threading.Tasks.Task alebo System.Threading.Tasks.Task. Zatiaľ čo prvé sa používa na vytvorenie úlohy, ktorá nevracia hodnotu, druhé sa používa na vytvorenie úloh, ktoré majú návratové hodnoty. Vlastnosť Task.Factory je inštanciou triedy TaskFactory. Táto vlastnosť sa používa na vytváranie a plánovanie úloh. Zatiaľ čo metóda Task.Factory.StartNew funguje ako operácia vidlice a slúži na vytváranie a spúšťanie nových úloh, metóda Wait funguje rovnako ako operácia spojenia a čaká na dokončenie úlohy.

Nasledujúci úryvok kódu ilustruje, ako môžete použiť metódu Task.Factory.StartNew.

Task.Factory.StartNew (() => TestMethod (), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);

Úlohu môžete vytvoriť aj pomocou metódy Task.Run, ako je uvedené v útržku kódu nižšie.

verejná asynchrónna úloha DoSomeWork ()

        {

await Task.Run (() => TestMethod ());

        }

void TestMethod ()

        {

Console.WriteLine („Ahoj svet!“);

        }

Ak chcete vrátiť hodnotu z úlohy, môžete využiť metódu Task.FromResult, ako je uvedené v útržku kódu nižšie.

verejná asynchrónna úloha DoSomeWork ()

   {

string text = await Task.FromResult (GetMessage ());

   }

súkromný reťazec GetMessage ()

   {

návrat "Hello world!";

   }

Úlohy môžete vytvárať aj pomocou delegáta alebo akcie. Nasledujúci úryvok kódu ukazuje, ako môžete vytvárať úlohy pomocou akcií a delegátov.

Úloha task1 = nová úloha (nová akcia (zobrazenie));

task1.Start ();

Úloha task2 = nová Úloha (delegát {Display ();});

task2.Start ();

Úlohy môžete vytvárať aj pomocou metód lamba a anonymných metód.

Task.Factory.StartNew a Task.Run

Task.Factory.StartNew je rýchly spôsob vytvorenia a spustenia úlohy. Všimnite si, že volanie Task.Factory.StartNew je funkčne ekvivalentné vytvoreniu inštancie úlohy a následnému volaniu metódy Start na inštancii. Neodporúča sa však používať z mnohých dôvodov. Ak chcete spustiť synchrónny kód, Task.Factory.StartNew nie je dobrá voľba.

Upozorňujeme, že ak je k dispozícii plánovač úloh, metóda StartNew vykoná úlohu v tomto plánovači úloh. Naopak, ak nie je k dispozícii plánovač, vykonal by úlohu na vlákne fondu vlákien. Je potrebné poznamenať, že Task.Factory.StartNew je predvolene nastavený na TaskScheduler.Current a nie na TaskScheduler.Default.

Upozorňujeme, že volanie funkcie Task.Run (action) je ekvivalentné tomuto vyhláseniu: Task.Factory.StartNew (action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Naopak, volanie Task.Factory.StartNew (action) je ekvivalentné tomuto vyhláseniu:

Task.Factory.StartNew (action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current);

Ak chcete použiť Task.Factory.StartNew, ak ste vytvorili vlastný plánovač úloh a explicitne mu odovzdáte inštanciu plánovača. Vždy by som odporúčal používať Task.Run, pretože je oveľa jednoduchší a má bezpečnejšie predvolené hodnoty. Inými slovami, mali by sme sa vyhnúť používaniu Task.Factory.StartNew, pokiaľ nie je potrebné vytvoriť plánovač úloh a potom ho explicitne odovzdať pri volaní metódy StartNew na vytvorenie novej úlohy a jej naplánovanie. Ak by ste mali metódu TaskFactory.StartNew používať efektívne a spoľahlivo, mali by ste použiť vlastný plánovač úloh a potom určiť CancellationToken a TaskCreationOptions.

Metódu Task.Run sa odporúča použiť, keď nepotrebujete mať príliš jemnú kontrolu nad plánovaním vlákien a ich zložitosťami. Task.Run by ste mali používať predovšetkým na metódach viazaných na procesor. Task.Run by ste však mali používať pri vyvolávaní úlohy, a nie v rámci implementácie úlohy. Inými slovami, Task.Run by ste nemali používať v žiadnej implementácii metódy, ale v mieste, kde sa metóda volá. Nasledujúci útržok kódu je príkladom „zlého“ kódu.

verejná asynchronná úloha DownloadDataFromWebAsync (Uri uri)

        {

návrat čaká Task.Run (() =>

            {

pomocou (WebClient webClient = nový WebClient ())

                {

vrátiť webClient.DownloadString (uri);

                }

            });

        }

Prečítajte si útržok kódu uvedený vyššie. Metóda nie je škálovateľná, pretože by blokovala vlákno na pozadí, získala vlákno z fondu vlákien a vykonávala sa na ňom synchrónne. Preto by to spotrebovalo viac zdrojov vo vašom systéme.

$config[zx-auto] not found$config[zx-overlay] not found