Kako izraditi vlastiti planer zadataka u C #

TPL (knjižnica paralelnih zadataka) jedna je od najzanimljivijih novih značajki u novijim verzijama .NET framework-a, koja je prvi put predstavljena u .NET Framework 4.0. Da biste radili s TPL-om, trebali biste iskoristiti prostor imena System.Threading.Tasks.

Što su planeri zadataka? Zašto su nam potrebni?

E sad, kako se planiraju zadaci? Pa, postoji komponenta koja se naziva raspored zadataka koja je odgovorna za raspoređivanje vaših zadataka. U osnovi, to je apstrakcija za objekt niske razine koji vaše zadatke može staviti u red na niti.

.NET Framework nudi vam dva planera zadataka. To uključuje zadani planer zadataka koji se izvodi na spremištu niti .NET framework-a i drugi planer zadataka koji se izvršava u kontekstu sinkronizacije određenog cilja. Imajte na umu da zadani planer zadataka TPL-a koristi prednost spremišta niti .NET Framework. Ovo spremište niti je zauzvrat predstavljeno klasom ThreadPool koja se nalazi unutar prostora imena System.Threading.Tasks.

Iako će zadani planer zadataka biti dovoljan većinu vremena, možda ćete htjeti izgraditi vlastiti prilagođeni planer zadataka koji će pružiti dodane funkcionalnosti, tj. Značajke koje zadani planer zadataka ne nudi. Takve značajke mogu uključivati, izvršavanje FIFO-a, stupanj istodobnosti itd.

Proširite klasu TaskScheduler na C #

Da biste izradili vlastiti prilagođeni planer zadataka, trebali biste stvoriti klasu koja proširuje klasu System.Threading.Tasks.TaskScheduler. Dakle, za izgradnju prilagođenog planera zadataka trebat ćete proširiti apstraktnu klasu TaskScheduler i nadjačati sljedeće metode.

  • QueueTask vraća void i prihvaća objekt Task kao parametar i ova metoda se poziva kada se zadatak treba zakazati
  • GetScheduledTasks vraća popis (točnije IEnumerable) svih zadataka koji su zakazani
  • TryExecuteTaskInline koristi se za izvršavanje zadataka u redu, tj. Na trenutnoj niti. U ovom se slučaju zadaci izvršavaju bez potrebe za redoslijedom

Sljedeći isječak koda pokazuje kako možete proširiti klasu TaskScheduler kako bi implementirao vaš prilagođeni rokovnik u C #.

javna klasa CustomTaskScheduler: TaskScheduler, IDisposable

    {

    }

Kao što smo raspravljali ranije u ovom članku, u prilagođenom planeru zadataka trebali biste poništiti metode GetScheduledTasks, QueueTask i TryExecuteTaskInline.

javno zapečaćena klasa CustomTaskScheduler: TaskScheduler, IDisposable

  {

        zaštićeno nadjačavanje IEnumerable GetScheduledTasks ()

        {

            //NAPRAVITI

        }

        zaštićeno poništavanje void QueueTask (zadatak zadatka)

        {

             //NAPRAVITI

        }

        zaštićeno poništavanje bool TryExecuteTaskInline (zadatak zadatka, zadatak boolWasPreviouslyQueued)

        {

            //NAPRAVITI

        }

        javna praznina Raspolagati ()

        {

            //NAPRAVITI

        }

  }

Koristite BlockingCollection za spremanje kolekcije objekata zadatka u C #

Krenimo sada s implementacijom našeg prilagođenog planera zadataka. Sljedeći isječak koda pokazuje kako možete iskoristiti BlockingCollection za spremanje kolekcije objekata zadatka.

javno zapečaćena klasa CustomTaskScheduler: TaskScheduler, IDisposable

 {

        private BlockingCollection tasksCollection = novo BlockingCollection ();

        privatno samo za čitanje Tema mainThread = null;

        javni CustomTaskScheduler ()

        {

            mainThread = nova nit (novi ThreadStart (izvršenje));

            ako (! mainThread.IsAlive)

            {

                mainThread.Start ();

            }

        }

        privatna praznina Izvrši ()

        {

            foreach (var zadatak u taskCollection.GetConsumingEnumerable ())

            {

                TryExecuteTask (zadatak);

            }

        } 

      // Ostale metode

  }

Pogledajte konstruktor klase CustomTaskScheduler. Imajte na umu kako je stvorena nova nit koja je pokrenula metodu Execute.

Implementirajte metode GetScheduledTasks, QueueTask i TryExecuteTaskInline u C #

Dalje, moramo implementirati tri metode koje moramo nadjačati u našem prilagođenom planeru zadataka. Te tri metode uključuju GetScheduledTasks, QueueTask i TryExecuteTaskInline.

Metoda GetScheduledTasks vraća instancu zbirke zadataka kao IEnumerable. To se koristi kako biste mogli nabrojati zbirku kako je prikazano u metodi Execute. Metoda QueueTask prihvaća objekt Task kao parametar i pohranjuje ga u zbirku zadataka. Metoda TryExecuteTaskInline nema implementaciju - prepustit ću čitatelju da je implementira.

zaštićeno nadjačavanje IEnumerable GetScheduledTasks ()

        {

            vratiti zadatkeCollection.ToArray ();

        }

        zaštićeno poništavanje void QueueTask (zadatak zadatka)

        {

            if (zadatak! = null)

                tasksCollection.Add (zadatak);

        }

        zaštićeno poništavanje bool TryExecuteTaskInline (zadatak zadatka, zadatak boolWasPreviouslyQueued)

        {

            return false;

        }

Kompletni primjer CustomTaskSchedulera na C #

Sljedeći popis kodova ilustrira konačnu verziju našeg CustomTaskSchedulera.

javno zapečaćena klasa CustomTaskScheduler: TaskScheduler, IDisposable

    {

        private BlockingCollection tasksCollection = novo BlockingCollection ();

        privatno samo za čitanje Tema mainThread = null;

        javni CustomTaskScheduler ()

        {

            mainThread = nova nit (novi ThreadStart (izvršenje));

            ako (! mainThread.IsAlive)

            {

                mainThread.Start ();

            }

        }

        privatna praznina Izvrši ()

        {

            foreach (var zadatak u taskCollection.GetConsumingEnumerable ())

            {

                TryExecuteTask (zadatak);

            }

        }

        zaštićeno nadjačavanje IEnumerable GetScheduledTasks ()

        {

            vratiti zadatkeCollection.ToArray ();

        }

        zaštićeno poništavanje void QueueTask (zadatak zadatka)

        {

            if (zadatak! = null)

                tasksCollection.Add (zadatak);           

        }

        zaštićeno poništavanje bool TryExecuteTaskInline (zadatak zadatka, zadatak boolWasPreviouslyQueued)

        {

            return false;

        }

        privatno void Dispose (zbrinjavanje bool-a)

        {

            if (! odlaganje) return;

            tasksCollection.CompleteAdding ();

            tasksCollection.Dispose ();

        }

        javna praznina Raspolagati ()

        {

            Raspolagati (istina);

            GC.SuppressFinalize (ovo);

        }

    }

Za upotrebu prilagođenog planera zadataka koji smo upravo implementirali možete upotrijebiti sljedeći isječak koda:

CustomTaskScheduler taskScheduler = novi CustomTaskScheduler ();

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

Kako učiniti više u C #:

  • Kada koristiti apstraktnu klasu naspram sučelja u C #
  • Kako raditi s AutoMapperom u C #
  • Kako koristiti lambda izraze u C #
  • Kako raditi s delegatima Action, Func i Predicate u C #
  • Kako raditi s delegatima u C #
  • Kako implementirati jednostavni zapisnik u C #
  • Kako raditi s atributima u C #
  • Kako raditi s log4netom na C #
  • Kako implementirati obrazac dizajna spremišta u C #
  • Kako raditi s refleksijom u C #
  • Kako raditi s nadzornikom datoteka u C #
  • Kako izvesti lijenu inicijalizaciju u C #
  • Kako raditi s MSM-om u C #
  • Kako raditi s metodama produženja u C #
  • Kako do nas lambda izrazi u C #
  • Kada upotrijebiti hlapljivu ključnu riječ u C #
  • Kako koristiti ključnu riječ yield u C #
  • Kako implementirati polimorfizam u C #
  • Kako izraditi vlastiti planer zadataka u C #
  • Kako raditi s RabbitM u C #
  • Kako raditi s korpicom u C #
  • Istraživanje virtualnih i apstraktnih metoda u C #