Ohjelmointi

Kuinka rakentaa oma tehtävän ajastin C #

TPL (Task Parallel Library) on yksi mielenkiintoisimmista uusista ominaisuuksista .NET-kehyksen viimeaikaisissa versioissa, ja se esiteltiin ensin .NET Framework 4.0: ssa. Jos haluat työskennellä TPL: n kanssa, sinun on hyödynnettävä System.Threading.Tasks-nimiavaruutta.

Mitä ovat tehtävien ajoittajat? Miksi me tarvitsemme niitä?

Kuinka tehtävät ajoitetaan nyt? On olemassa komponentti nimeltä tehtävien ajoitus, joka on vastuussa tehtävien ajoituksesta. Pohjimmiltaan se on abstraktio matalan tason objektille, joka voi jonottaa tehtävänne ketjuihin.

.NET Framework tarjoaa sinulle kaksi tehtävien ajoitusta. Näihin kuuluvat oletusarvoinen tehtävien ajoitus, joka toimii .NET-kehyskierrealalla, ja toinen tehtävien ajoitus, joka suorittaa määritetyn kohteen synkronointikontekstissa. Huomaa, että TPL: n oletustehtävien ajoitus käyttää .NET Framework -ketjujoukkoa. Tätä säikejoukkoa puolestaan ​​edustaa ThreadPool-luokka, joka on System.Threading.Tasks-nimitilassa.

Vaikka oletustehtävien ajoitus riittää suurimman osan ajasta, saatat haluta rakentaa oman mukautetun tehtävien ajoituksen, jotta saat lisätoimintoja eli ominaisuuksia, joita oletusarvoinen tehtävien ajoitus ei tarjoa. Tällaisia ​​ominaisuuksia voivat olla esimerkiksi FIFO-toteutus, samanaikaisuuden aste jne.

Laajenna TaskScheduler-luokkaa luokassa C #

Oman mukautetun tehtävien ajoituksen rakentamiseksi sinun on luotava luokka, joka laajentaa System.Threading.Tasks.TaskScheduler-luokkaa. Joten, jotta voit luoda mukautetun tehtävien ajoituksen, sinun on laajennettava TaskScheduler-abstraktiluokkaa ja ohitettava seuraavat menetelmät.

  • QueueTask palauttaa void-arvon ja hyväksyy Task-objektin parametrina. Tätä menetelmää kutsutaan, kun tehtävä on ajoitettava
  • GetScheduledTasks palauttaa luettelon (täsmällinen I-luku) kaikista ajoitetuista tehtävistä
  • TryExecuteTaskInlinea käytetään tehtävien suorittamiseen linjassa, ts. Nykyisessä säikeessä. Tässä tapauksessa tehtävät suoritetaan ilman tarvetta jonottaa niitä

Seuraava koodinpätkä osoittaa, kuinka voit laajentaa TaskScheduler-luokkaa mukautetun ajastimen toteuttamiseksi C #: ssä.

julkinen luokka CustomTaskScheduler: TaskScheduler, IDisposable

    {

    }

Kuten keskustelimme aiemmin tässä artikkelissa, sinun on ohitettava GetScheduledTasks-, QueueTask- ja TryExecuteTaskInline-menetelmät mukautetussa tehtävien ajoituksessa.

julkinen sinetöity luokka CustomTaskScheduler: TaskScheduler, IDisposable

  {

suojattu ohitus IEnumerable GetScheduledTasks ()

        {

//TEHDÄ

        }

suojattu ohittaa void QueueTask (Tehtävätehtävä)

        {

//TEHDÄ

        }

suojattu ohitus bool TryExecuteTaskInline (Tehtävätehtävä, Bool taskWasPreviouslyQueued)

        {

//TEHDÄ

        }

public void Hävitä ()

        {

//TEHDÄ

        }

  }

Käytä BlockingCollection-toimintoa tallentaaksesi kokoelman tehtäväobjekteja C #: een

Aloitetaan nyt mukautetun tehtävien ajoituksen toteuttaminen. Seuraava koodinpätkä osoittaa, kuinka voit käyttää BlockingCollection-sovellusta kokoamaan tehtäväobjekteja.

julkinen sinetöity luokka CustomTaskScheduler: TaskScheduler, IDisposable

 {

yksityinen BlockingCollection taskCollection = uusi BlockingCollection ();

yksityinen vain lukea Kierre mainThread = null;

julkinen CustomTaskScheduler ()

        {

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

if (! mainThread.IsAlive)

            {

mainThread.Start ();

            }

        }

private void Suorita ()

        {

foreach (var task taskCollection.GetConsumingEnumerable ())

            {

TryExecuteTask (tehtävä);

            }

        } 

// Muut menetelmät

  }

Katso lisätietoja CustomTaskScheduler-luokan rakentajasta. Huomaa, kuinka uusi ketju on luotu ja aloitettu suorittamaan Execute-menetelmä.

Toteuta GetScheduledTasks-, QueueTask- ja TryExecuteTaskInline-menetelmät C #: ssä

Seuraavaksi meidän on toteutettava kolme tapaa, jotka meidän on ohitettava mukautetussa tehtävien ajoittajamme. Nämä kolme menetelmää sisältävät GetScheduledTasks, QueueTask ja TryExecuteTaskInline.

GetScheduledTasks-menetelmä palauttaa tehtäväkokoelman esiintymän muodossa IEnumerable. Tätä käytetään, jotta voit luetella kokoelman Execute-menetelmän mukaisesti. QueueTask-menetelmä hyväksyy tehtäväobjektin parametrina ja tallentaa sen tehtäväkokoelmaan. TryExecuteTaskInline-menetelmällä ei ole toteutusta - jätän sen lukijan tehtäväksi toteuttaa se.

suojattu ohitus IEnumerable GetScheduledTasks ()

        {

palauttaa tehtävätCollection.ToArray ();

        }

suojattu ohittaa void QueueTask (Tehtävätehtävä)

        {

if (tehtävä! = tyhjä)

taskCollection.Add (tehtävä);

        }

suojattu ohittaa Bool TryExecuteTaskInline (Tehtävätehtävä, Bool taskWasPreviouslyQueued)

        {

return false;

        }

Täydellinen CustomTaskScheduler-esimerkki C #: ssä

Seuraava koodiluettelo kuvaa CustomTaskScheduler-sovelluksen lopullisen version.

julkinen sinetöity luokka CustomTaskScheduler: TaskScheduler, IDisposable

    {

yksityinen BlockingCollection taskCollection = uusi BlockingCollection ();

yksityinen vain lukea Viestiketju mainThread = null;

julkinen CustomTaskScheduler ()

        {

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

if (! mainThread.IsAlive)

            {

mainThread.Start ();

            }

        }

private void Suorita ()

        {

foreach (var task taskCollection.GetConsumingEnumerable ())

            {

TryExecuteTask (tehtävä);

            }

        }

suojattu ohitus IEnumerable GetScheduledTasks ()

        {

palauttaa tehtävätCollection.ToArray ();

        }

suojattu ohittaa void QueueTask (Tehtävätehtävä)

        {

if (tehtävä! = tyhjä)

taskCollection.Add (tehtävä);

        }

suojattu ohitus bool TryExecuteTaskInline (Tehtävätehtävä, Bool taskWasPreviouslyQueued)

        {

return false;

        }

private void Hävitä (bool-hävitys)

        {

jos (! hävittäminen) paluu;

taskCollection.CompleteAdding ();

taskCollection.Dispose ();

        }

public void Hävitä ()

        {

Hävitä (true);

GC.SuppressFinalize (tämä);

        }

    }

Voit käyttää juuri toteuttamaamme mukautettua tehtävien ajoitinta käyttämällä seuraavaa koodinpätkää:

CustomTaskScheduler taskScheduler = uusi CustomTaskScheduler ();

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

Kuinka tehdä enemmän C #: ssä:

  • Milloin abstraktia luokkaa vs. käyttöliittymää käytetään C #: ssä
  • Kuinka työskennellä AutoMapperin kanssa C #: ssä
  • Kuinka käyttää lambda-lausekkeita C #: ssä
  • Kuinka toimia Action-, Func- ja Predicate-edustajien kanssa C #: ssä
  • Kuinka työskennellä C #: n edustajien kanssa
  • Kuinka toteuttaa yksinkertainen kirjaaja C #: ssä
  • Kuinka työskennellä attribuuttien kanssa C #: ssä
  • Kuinka työskennellä log4netin kanssa C #: ssä
  • Kuinka toteuttaa arkiston suunnittelumalli C #: ssä
  • Kuinka työskennellä heijastuksen kanssa C #: ssä
  • Kuinka työskennellä tiedostojärjestelmän katselijan kanssa C #: ssä
  • Kuinka tehdä laiska alustus C #: ssä
  • Kuinka työskennellä MSM: n kanssa C #: ssä
  • Kuinka työskennellä laajennusmenetelmien kanssa C #: ssä
  • Kuinka meille lambda-lausekkeet C #: ssä
  • Milloin haihtuvaa avainsanaa käytetään C #: ssä
  • Tuottoavainsanan käyttäminen C #: ssä
  • Kuinka toteuttaa polymorfismi C #: ssa
  • Kuinka rakentaa oma tehtävän ajastin C #
  • Kuinka työskennellä RabbitM: n kanssa C #: ssä
  • Kuinka työskennellä C #: n kanssa
  • Virtuaalisten ja abstraktien menetelmien tutkiminen C #: ssä