Programovanie

Ako zostaviť vlastný plánovač úloh v C #

TPL (Task Parallel Library) je jednou z najzaujímavejších nových funkcií v posledných verziách rozhrania .NET, ktorá bola prvýkrát predstavená v rozhraní .NET Framework 4.0. Aby ste mohli pracovať s TPL, musíte využiť výhody menného priestoru System.Threading.Tasks.

Čo sú plánovače úloh? Prečo ich potrebujeme?

Ako je to s naplánovaním úloh? Existuje však komponent nazývaný plánovač úloh, ktorý je zodpovedný za plánovanie vašich úloh. V zásade ide o abstrakciu pre objekt nízkej úrovne, ktorý dokáže zaradiť vaše úlohy do frontu na vlákna.

.NET Framework vám poskytuje dva plánovače úloh. Patrí medzi ne predvolený plánovač úloh, ktorý je spustený vo fonde vlákien .NET framework, a ďalší plánovač úloh, ktorý sa spúšťa v synchronizačnom kontexte zadaného cieľa. Všimnite si, že predvolený plánovač úloh TPL využíva fond vlákien .NET Framework. Tento fond vlákien je zase reprezentovaný triedou ThreadPool, ktorá je obsiahnutá vo vnútri priestoru názvov System.Threading.Tasks.

Aj keď predvolený plánovač úloh bude väčšinu času stačiť, možno budete chcieť vytvoriť svoj vlastný vlastný plánovač úloh, ktorý poskytne ďalšie funkcie, t. J. Funkcie, ktoré predvolený plánovač úloh neposkytuje. Medzi tieto funkcie môže patriť vykonávanie FIFO, stupeň súbežnosti atď.

Rozšírenie triedy TaskScheduler v C #

Ak chcete vytvoriť svoj vlastný plánovač úloh, budete musieť vytvoriť triedu, ktorá rozširuje triedu System.Threading.Tasks.TaskScheduler. Aby ste teda mohli zostaviť vlastný plánovač úloh, budete musieť rozšíriť abstraktnú triedu TaskScheduler a prepísať nasledujúce metódy.

  • QueueTask vracia void a prijíma objekt úlohy ako parameter a táto metóda sa volá, keď sa má naplánovať úloha
  • GetScheduledTasks vráti zoznam (presnejšie IEnumerable) všetkých úloh, ktoré boli naplánované
  • TryExecuteTaskInline sa používa na vykonávanie úloh inline, t. J. Na aktuálnom vlákne. V takom prípade sú úlohy vykonané bez potreby zaradenia do poradia

Nasledujúci úryvok kódu ukazuje, ako môžete rozšíriť triedu TaskScheduler a implementovať svoj vlastný plánovač v C #.

verejná trieda CustomTaskScheduler: TaskScheduler, IDisposable

    {

    }

Ako sme už diskutovali vyššie v tomto článku, bolo by potrebné prepísať metódy GetScheduledTasks, QueueTask a TryExecuteTaskInline vo vlastnom plánovači úloh.

verejná zapečatená trieda CustomTaskScheduler: TaskScheduler, IDisposable

  {

chránené prepísanie IEnumerable GetScheduledTasks ()

        {

//ROBIŤ

        }

protected override void QueueTask (úloha)

        {

//ROBIŤ

        }

chránené prepísanie bool TryExecuteTaskInline (úloha task, bool taskWasPreviouslyQueued)

        {

//ROBIŤ

        }

public void Dispose ()

        {

//ROBIŤ

        }

  }

Použite BlockingCollection na uloženie kolekcie objektov úloh v C #

Začnime teraz implementovať náš vlastný plánovač úloh. Nasledujúci úryvok kódu ukazuje, ako môžete využiť funkciu BlockingCollection na uloženie kolekcie objektov úloh.

verejná zapečatená trieda CustomTaskScheduler: TaskScheduler, IDisposable

 {

private BlockingCollection tasksCollection = new BlockingCollection ();

súkromné ​​iba na čítanie Vlákno mainThread = null;

public CustomTaskScheduler ()

        {

mainThread = new Thread (new ThreadStart (Execute));

if (! mainThread.IsAlive)

            {

mainThread.Start ();

            }

        }

private void Execute ()

        {

foreach (var úloha v tasksCollection.GetConsumingEnumerable ())

            {

TryExecuteTask (úloha);

            }

        } 

// Ostatné metódy

  }

Pozrite si konštruktor triedy CustomTaskScheduler. Všimnite si, ako bolo nové vlákno vytvorené a ako bolo spustené spustenie metódy Execute.

Implementujte metódy GetScheduledTasks, QueueTask a TryExecuteTaskInline v C #

Ďalej musíme implementovať tri metódy, ktoré musíme prepísať v našom vlastnom plánovači úloh. Medzi tieto tri metódy patria GetScheduledTasks, QueueTask a TryExecuteTaskInline.

Metóda GetScheduledTasks vracia inštanciu kolekcie úloh ako IEnumerable. Používa sa na to, aby ste mohli vymenovať kolekciu, ako je uvedené v metóde Execute. Metóda QueueTask prijíma objekt úlohy ako parameter a ukladá ho do zbierky úloh. Metóda TryExecuteTaskInline nemá implementáciu - implementáciu nechám na čitateľa.

chránené prepísanie IEnumerable GetScheduledTasks ()

        {

return tasksCollection.ToArray ();

        }

protected override void QueueTask (úloha)

        {

if (task! = null)

tasksCollection.Add (úloha);

        }

chránené prepísanie bool TryExecuteTaskInline (úloha task, bool taskWasPreviouslyQueued)

        {

návrat nepravdivý;

        }

Kompletný príklad CustomTaskScheduler v C #

Nasledujúci zoznam kódov ilustruje finálnu verziu nášho nástroja CustomTaskScheduler.

verejná zapečatená trieda CustomTaskScheduler: TaskScheduler, IDisposable

    {

private BlockingCollection tasksCollection = new BlockingCollection ();

súkromné ​​iba na čítanie Vlákno mainThread = null;

verejný CustomTaskScheduler ()

        {

mainThread = new Thread (new ThreadStart (Execute));

if (! mainThread.IsAlive)

            {

mainThread.Start ();

            }

        }

private void Execute ()

        {

foreach (var úloha v tasksCollection.GetConsumingEnumerable ())

            {

TryExecuteTask (úloha);

            }

        }

chránené prepísanie IEnumerable GetScheduledTasks ()

        {

return tasksCollection.ToArray ();

        }

protected override void QueueTask (úloha)

        {

if (task! = null)

tasksCollection.Add (úloha);

        }

chránené prepísanie bool TryExecuteTaskInline (úloha task, bool taskWasPreviouslyQueued)

        {

návrat nepravdivý;

        }

private void Dispose (bool disposing)

        {

ak sa (! likviduje) vráti;

tasksCollection.CompleteAdding ();

tasksCollection.Dispose ();

        }

public void Dispose ()

        {

Zlikvidujte (pravda);

GC.SuppressFinalize (this);

        }

    }

Ak chcete použiť vlastný plánovač úloh, ktorý sme práve implementovali, môžete použiť nasledujúci útržok kódu:

CustomTaskScheduler taskScheduler = nový CustomTaskScheduler ();

Task.Factory.StartNew (() => SomeMethod (), CancellationToken.None, TaskCreationOptions.None, taskScheduler);

Ako urobiť viac v C #:

  • Kedy použiť abstraktné rozhranie vs. rozhranie v C #
  • Ako pracovať s AutoMapperom v C #
  • Ako používať výrazy lambda v C #
  • Ako pracovať s delegátmi Action, Func a Predicate v C #
  • Ako pracovať s delegátmi v C #
  • Ako implementovať jednoduchý záznamník v C #
  • Ako pracovať s atribútmi v C #
  • Ako pracovať s log4net v C #
  • Ako implementovať vzor návrhu úložiska v C #
  • Ako pracovať s odrazom v C #
  • Ako pracovať so súborovým systémom v C #
  • Ako vykonať lenivú inicializáciu v C #
  • Ako pracovať s MSM v C #
  • Ako pracovať s metódami rozšírenia v C #
  • Ako na nás výrazy lambda v C #
  • Kedy použiť volatile kľúčové slovo v C #
  • Ako používať kľúčové slovo výťažku v C #
  • Ako implementovať polymorfizmus v C #
  • Ako zostaviť vlastný plánovač úloh v C #
  • Ako pracovať s RabbitM v C #
  • Ako pracovať s n-ticí v C #
  • Skúmanie virtuálnych a abstraktných metód v C #
$config[zx-auto] not found$config[zx-overlay] not found