Programavimas

Kaip sukurti savo užduočių planavimo priemonę C #

TPL („Task Parallel Library“) yra viena įdomiausių naujų funkcijų naujausiose .NET Framework versijose, kuri pirmą kartą buvo pristatyta .NET Framework 4.0. Norėdami dirbti su TPL, turėtumėte pasinaudoti „System.Threading.Tasks“ vardų srities pranašumais.

Kas yra užduočių planuotojai? Kodėl mums jų reikia?

Kaip planuojamos užduotys? Na, yra komponentas, vadinamas užduočių planuotoju, kuris yra atsakingas už jūsų užduočių planavimą. Iš esmės tai yra žemo lygio objekto abstrakcija, kuri gali sudaryti eilę jūsų užduotims.

.NET Framework suteikia jums du užduočių planuoklius. Tai apima numatytąjį užduočių planuoklį, kuris veikia .NET Framework gijų telkinyje, ir kitą užduočių planuoklį, vykdantį nurodyto tikslo sinchronizavimo kontekste. Atminkite, kad numatytasis TPL užduočių planuoklis naudoja .NET Framework gijų rinkinį. Šį gijų grupę savo ruožtu vaizduoja „ThreadPool“ klasė, esanti sistemoje. Threading.Tasks vardų sritis.

Nors numatytojo užduočių planavimo priemonės dažniausiai pakaks, galbūt norėsite sukurti savo pasirinktinį užduočių planavimo priemonę, kad suteiktų papildomų funkcijų, t. Y. Funkcijas, kurių neteikia numatytasis užduočių planuoklis. Tokios savybės gali būti FIFO vykdymas, sutapimo laipsnis ir kt.

Išplėskite „TaskScheduler“ klasę C #

Norėdami sukurti savo pasirinktinį užduočių planuoklį, turėsite sukurti klasę, pratęsiančią „System.Threading.Tasks.TaskScheduler“ klasę. Taigi, norėdami sukurti pasirinktinį užduočių planavimo įrankį, turėsite išplėsti „TaskScheduler“ abstrakčią klasę ir nepaisyti šių metodų.

  • „QueueTask“ grąžina negaliojančią ir priima užduoties objektą kaip parametrą, ir šis metodas iškviečiamas, kai reikia suplanuoti užduotį
  • „GetScheduledTasks“ pateikia visų suplanuotų užduočių sąrašą (tiksliau - ISkaičiuojamą skaičių)
  • „TryExecuteTaskInline“ naudojamas užduotims vykdyti tiesiai, t. Y. Dabartinei gijai. Šiuo atveju užduotys vykdomos be poreikio jas sudėti į eilę

Šis kodo fragmentas parodo, kaip galite išplėsti „TaskScheduler“ klasę, kad įdiegtumėte savo pasirinktinį planavimo priemonę C #.

public class CustomTaskScheduler: TaskScheduler, IDisposable

    {

    }

Kaip aptarėme anksčiau šiame straipsnyje, jums reikės nepaisyti „GetScheduledTasks“, „QueueTask“ ir „TryExecuteTaskInline“ metodų pasirinktinių užduočių planavimo priemonėje.

viešoji sandari klasė CustomTaskScheduler: TaskScheduler, IDisposable

  {

apsaugotas nepaisymas IEnumerable GetScheduledTasks ()

        {

//DARYTI

        }

apsaugotas anuliuoti negaliojančią „QueueTask“ (užduoties užduotis)

        {

//DARYTI

        }

apsaugotas nepaisyti „Bool TryExecuteTaskInline“ (užduoties užduotis, „Bool taskWasPreviouslyQueued“)

        {

//DARYTI

        }

public void Dispose ()

        {

//DARYTI

        }

  }

Naudokite „BlockingCollection“, kad išsaugotumėte užduočių objektų rinkinį C #

Dabar pradėkime diegti savo pasirinktinį užduočių planuoklį. Šis kodo fragmentas parodo, kaip galite panaudoti „BlockingCollection“, kad išsaugotumėte užduočių objektų kolekciją.

viešoji sandari klasė CustomTaskScheduler: TaskScheduler, IDisposable

 {

privatus „BlockingCollection“ užduotisCollection = naujas „BlockingCollection“ ();

privatus tik skaitomas gija mainThread = null;

public CustomTaskScheduler ()

        {

mainThread = nauja gija (nauja ThreadStart (Execute));

jei (! mainThread.IsAlive)

            {

mainThread.Start ();

            }

        }

privatus negaliojantis Vykdyti ()

        {

foreach (var task in taskCollection.GetConsumingEnumerable ())

            {

TryExecuteTask (užduotis);

            }

        } 

// Kiti metodai

  }

Žr. „CustomTaskScheduler“ klasės konstruktorių. Atkreipkite dėmesį, kaip sukurta nauja gija ir pradėtas vykdyti metodas Vykdyti.

Įdiekite „GetScheduledTasks“, „QueueTask“ ir „TryExecuteTaskInline“ metodus C #

Tada turime įdiegti tris metodus, kuriuos turime nepaisyti pasirinktinių užduočių planavimo priemonėje. Šie trys metodai apima „GetScheduledTasks“, „QueueTask“ ir „TryExecuteTaskInline“.

„GetScheduledTasks“ metodas grąžina užduočių rinkinio egzempliorių kaip „IEnumerable“. Tai naudojama tam, kad galėtumėte surašyti kolekciją, kaip parodyta vykdymo metodu. Metodas „QueueTask“ priima užduoties objektą kaip parametrą ir saugo jį užduočių rinkinyje. TryExecuteTaskInline metodas nėra įgyvendinamas - paliksiu skaitytojui jį įgyvendinti.

apsaugotas nepaisymas IEnumerable GetScheduledTasks ()

        {

grąžinti užduotisCollection.ToArray ();

        }

apsaugotas anuliuoti negaliojančią „QueueTask“ (užduoties užduotis)

        {

jei (užduotis! = nulinė)

taskCollection.Add (užduotis);

        }

apsaugotas nepaisyti „Bool TryExecuteTaskInline“ (užduoties užduotis, „Bool taskWasPreviouslyQueued“)

        {

grąžinti klaidingą;

        }

Užpildykite „CustomTaskScheduler“ pavyzdį C #

Šis kodų sąrašas iliustruoja galutinę „CustomTaskScheduler“ versiją.

viešoji sandari klasė CustomTaskScheduler: TaskScheduler, IDisposable

    {

privatus „BlockingCollection“ užduotisCollection = naujas „BlockingCollection“ ();

privatus tik skaitomas gija mainThread = null;

public CustomTaskScheduler ()

        {

mainThread = nauja gija (nauja ThreadStart (Execute));

jei (! mainThread.IsAlive)

            {

mainThread.Start ();

            }

        }

privatus negaliojantis Vykdyti ()

        {

foreach (var task in taskCollection.GetConsumingEnumerable ())

            {

TryExecuteTask (užduotis);

            }

        }

apsaugotas nepaisymas IEnumerable GetScheduledTasks ()

        {

grąžinti užduotisCollection.ToArray ();

        }

apsaugotas anuliuoti negaliojančią „QueueTask“ (užduoties užduotis)

        {

jei (užduotis! = nulinė)

taskCollection.Add (užduotis);

        }

apsaugotas nepaisyti „Bool TryExecuteTaskInline“ (užduoties užduotis, „Bool taskWasPreviouslyQueued“)

        {

grąžinti klaidingą;

        }

privatus tuštumas Išmeskite („Bool“ šalinimas)

        {

jei (! disponuoja) grįžti;

taskCollection.CompleteAdding ();

taskCollection.Dispose ();

        }

public void Dispose ()

        {

Disponuoti (tiesa);

GC.SuppressFinalize (tai);

        }

    }

Norėdami naudoti ką tik įdiegtą tinkintą užduočių planavimo priemonę, galite naudoti šį kodo fragmentą:

CustomTaskScheduler taskScheduler = new CustomTaskScheduler ();

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

Kaip padaryti daugiau C #:

  • Kada naudoti abstrakčią klasę ir sąsają C #
  • Kaip dirbti su „AutoMapper“ C #
  • Kaip naudoti lambda išraiškas C #
  • Kaip dirbti su „Action“, „Func“ ir „Predicate“ delegatais C #
  • Kaip dirbti su delegatais C #
  • Kaip įdiegti paprastą kaupiklį C #
  • Kaip dirbti su atributais C #
  • Kaip dirbti su „Log4net“ C #
  • Kaip įgyvendinti saugyklos dizaino modelį C #
  • Kaip dirbti su atspindžiu C #
  • Kaip dirbti su failų stebėjimo programa C #
  • Kaip atlikti tingų inicializavimą C #
  • Kaip dirbti su MSM C #
  • Kaip dirbti su plėtinių metodais C #
  • Kaip mums lambda išraiškos C #
  • Kada naudoti nepastovų raktinį žodį C #
  • Kaip naudoti pajamingumo raktinį žodį C #
  • Kaip įgyvendinti polimorfizmą C #
  • Kaip sukurti savo užduočių planavimo priemonę C #
  • Kaip dirbti su „RabbitM“ C #
  • Kaip dirbti su dvigubu C #
  • Naršyti virtualius ir abstrakčius metodus C #