Ohjelmointi

Kaksi senttiäni langassa. Abortti ja säie. Keskeytysmenetelmät

Kohdassa C # saatat joutua usein julkaisemaan estetyn säikeen. Tämän saavuttamiseksi on olemassa kaksi tapaa, joita voit hyödyntää. Näitä ovat Thread.Abort ja Thread.Interrupt -menetelmät.

Mitä Thread.Abort-menetelmä tekee?

Voit lopettaa ketjun käyttämällä Thread-luokan Abort-menetelmää. Huomaa, että ketjun lopettamisprosessin aloittamiseksi Thread-luokan Abort-menetelmä, kun sitä kutsutaan, nostaa ThreadAbortException-ketjun, johon sitä on kutsuttu. On huomattava, että voit hyödyntää Thread-luokan Abort-menetelmää lopettaaksesi jopa lukitsemattoman säikeen. Jos keskeytettävä säie on odottavassa tilassa, se herättää sen ja aiheuttaa sitten ThreadInterruptedException-heiton. Vastaavasti, jos soitat Thread.Abort-menetelmää odottavassa säikeessä, ajonaika herättää langan ja heittää sitten ThreadAbortExceptionin.

Voit napata ThreadAbortException-saalislohkon. Jos et kuitenkaan kutsu ResetAbort-menetelmää, tämä poikkeus heitetään uudelleen kiinniottolohkon loppuun. Kutsu ResetAbort-menetelmään estää ThreadAbortExceptionin heittämisen uudelleen kiinniottolohkon loppuun. Toisin kuin Thread.Inturrupt-menetelmät toimivat, jos säiettä, jolle Thread.Abort-menetelmää kutsutaan, ei ole estetty, Thread.Abort-menetelmä heittää ThreadAbortException-ketjun.

Useimmissa tapauksissa (ellet halua sulkea sovellustunnusta ketjun keskeyttämisen jälkeen), sinun ei tarvitse käyttää tätä menetelmää ollenkaan. Huomaa, että ASP.Netin Response.Redirect-menetelmä heittää ThreadAbortExceptionin.

Mikä on Thread.Interrupt-menetelmän tarkoitus?

Voit keskeyttää langan, joka on WaitSleepJoin-tilassa, Thread.Interrupt-menetelmällä. Mikään näistä lähestymistavoista (Thread.Abort tai Thread.Interrupt menetelmäpuhelut) ei kuitenkaan ole säiettä turvallinen. Samalla kun Thread.Abort-menetelmä heittää ThreadAbortExceptionin, Thread.Interrupt-menetelmä heittää ThreadInterruptExceptionin. Pohjimmiltaan kutsu Thread.Interrupt-menetelmällä katkaisee langan ja heittää ThreadInterruptedExceptionin keskeyttääkseen langan estävän puhelun sisällä. Sinun tulisi käsitellä tätä poikkeusta koodissasi, jollei ajoaika pysäytä säie, johon Thread.Interrupt-menetelmä on kutsuttu. On huomattava, että kutsu Thread.Interrupt ei keskeytä ketjua, joka suorittaa hallitsematonta koodia.

Harkitse seuraavaa koodiluetteloa, joka kuvaa kuinka Thread.Interrupt-menetelmä voidaan kutsua väkisin katkaisemaan ketju.

staattinen void Main (merkkijono [] args)

       {

Langankierre = uusi ketju (ThreadMethod);

lanka.Käynnistä ();

lanka.Katkaise ();

Konsoli.Lue ();

       }

yksityinen staattinen void ThreadMethod ()

       {

yrittää

           {

Thread.Sleep (Timeout.Infinite);

           }

saalis (ThreadInterruptedException)

           {

Console.Write ("ThreadInterruptedException on kutsuttu pakolla.");

           }

       }

Kun yllä mainittu ohjelma on suoritettu, viesti "ThreadInterruptedException on kutsuttu pakotetusti" näkyy konsolissa.

Mitä tapahtuu, jos keskeytettävää säiettä ei estetä? Soitan Threadille. Keskeytä langalle, jota ei ole estetty, ketju jatkuu, kunnes se estetään seuraavaksi. Useimmissa tapauksissa sinun ei tarvitse käyttää Thread.Ininterruptia lainkaan. Voit saavuttaa saman käyttämällä merkinantorakenteita tai peruutustunnuksia.

Pitäisikö minun käyttää Thread.Abort- tai Thread.Interrupt-menetelmää?

Joten milloin minun pitäisi käyttää Thread.Abort vs Thread.Interrupt -menetelmiä ohjelmassa? Mitä minun on käytettävä, jos minun on peruutettava tietty toiminto? Rehellinen vastaukseni on, että sinun ei koskaan pidä käyttää kumpaakaan näistä menetelmistä ketjun lopettamiseksi. On suositeltavaa olla käyttämättä Thread.Abort- tai Thread.Interrup-menetelmiä ketjun lopettamiseksi - sinun on pikemminkin hyödynnettävä synkronointikohteita (kuten WaitHandles tai Semaphores) ja suoritettava käyttämäsi säikeet sulavasti. Seuraava koodinpätkä kuvaa, kuinka voit käyttää WaitHandle-ohjelmaa, jotta ketju pysähtyy sulavasti.

yksityinen mitätön ThreadMethod ()

{

while (! manualResetEventObject.WaitOne (TimeSpan.FromMilliseconds (100)))

   {

// Kirjoita koodi tähän

   }

}

Vaihtoehtoisena tapana päättää ketju sulavasti, voit myös hyödyntää haihtuvaa "loogista" muuttujaa. Tämän jälkeen voit asettaa tämän muuttujan käyttöliittymäkierteessä joillekin käyttäjätoiminnoille (olettaen, että käyttäjä on napsauttanut käyttöliittymän "Peruuta" -painiketta lopettaaksesi ketjun) ja tarkista sitten muuttujan arvo aika ajoin Työntekijässä säiettä nähdäksesi, onko muuttuja asetettu (ehkä arvo "false" ilmaisemaan ketjun päättymistä) käyttöliittymässä.