.NET: Utauta mo te mahi me te miro maha me te tukutahi. Wāhanga 1

Kei te whakaputa ahau i te tuhinga taketake mo Habr, ko te whakamaoritanga e whakairihia ana ki te umanga pou pou.

Ko te hiahia ki te mahi i tetahi mea, me te kore e tatari mo te hua i konei me inaianei, ki te wehewehe ranei i nga mahi nui i roto i nga waahanga maha e mahi ana, i mua i te taenga mai o nga rorohiko. I to ratou taenga mai, ka tino kitea tenei hiahia. Inaianei, i te tau 2019, kei te tuhi ahau i tenei tuhinga ki runga i te pona me te 8-matua Intel Core tukatuka, neke atu i te kotahi rau nga tukanga e rere whakarara ana, me etahi atu miro. Kei te taha tata, he waea paku noa, kua hokona mai i nga tau e rua ki muri, he 8-matua te tukatuka kei runga. Ko nga rauemi kaupapa kua ki tonu i nga tuhinga me nga riipene ataata e miharo ana o ratou kaituhi ki nga waea atamai rongonui o tenei tau e whakaatu ana i nga tukatuka 16-matua. Ka whakaratohia e MS Azure he miihini mariko me te tukatuka matua 20 me te 128 TB RAM mo te iti iho i te $2/haora. Kia aroha mai, kaore e taea te tango i te nui me te whakamahi i tenei mana me te kore e kaha ki te whakahaere i te taunekeneke o nga miro.

Te Terminology

Tukanga - Ahanoa OS, mokowā wāhitau motuhake, kei roto nga miro.
Miro - he ahanoa OS, te waeine iti rawa o te mahi, he wahanga o te tukanga, ka tiritiri nga miro i te mahara me etahi atu rauemi ki a ratou ano i roto i tetahi mahi.
Te tini - Nga taonga OS, te kaha ki te whakahaere i nga mahi maha i te wa kotahi
Matua-maha - he taonga o te kaitukatuka, te kaha ki te whakamahi i nga kohao maha mo te tukatuka raraunga
Tukatuka maha - he taonga o te rorohiko, te kaha ki te mahi tahi me te maha o nga kaitukatuka tinana
Panui-maha - he taonga o te tukanga, te kaha ki te tohatoha tukatuka raraunga i roto i nga miro maha.
Whakarara - he maha nga mahi a tinana i te wa kotahi
Tukutahi - te mahi i tetahi mahi me te kore e tatari mo te otinga o tenei mahi; ka taea te mahi i muri mai te hua o te mahi.

Tuhinga o mua

Ehara i te mea he pai nga whakamaramatanga katoa, me etahi atu whakamaramatanga, no reira ka taapirihia e au he kupu whakarite mo te tunu parakuihi ki nga kupu kua whakauruhia. Ko te tunu parakuihi i roto i tenei kupu whakarite he tukanga.

I a au e whakarite ana i te parakuihi i te ata (PTM) Haere mai ahau ki te kīhini (Rorohiko). E rua oku ringa (otaota). He maha nga taputapu kei roto i te kihini (IO): oumu, kettle, toaster, pouaka whakamātao. Ka whakakāhia e ahau te hau, ka maka he parai ki runga ka ringihia he hinu ki roto me te kore e tatari kia wera (asynchronously, Kore-Aukati-IO-Tatari), Ka tangohia e ahau nga hua i roto i te pouaka whakamātao ka wahia ki te pereti, ka whiua ki te ringa kotahi (Miro #1), me te tuarua (Miro #2) e mau ana i te pereti (Shared Resource). Inaianei kei te pirangi au ki te whakaka i te ketere, engari karekau oku ringaringa (Miro matekai) I tenei wa, ka wera te parai (Tukatuka i te hua) ka ringihia e ahau te mea i whiua e ahau. Ka toro atu ahau ki te ipu ka whakahurihia, ka titiro poauau ki te koropuputanga o te wai (Poraka-IO-Tatari), ahakoa i tenei wa ka taea e ia te horoi i te pereti i whiua e ia te omelet.

I tunua e ahau he omelette ma te whakamahi i nga ringa e 2 anake, karekau he maha atu, engari i te wa ano, i te wa o te whiu i te omelette, e toru nga mahi i te wa kotahi: te whiu i te omeleti, te pupuri i te pereti, te whakamahana i te parai. Ko te PTM te waahanga tere o te rorohiko, ko te IO te nuinga o nga wa ka puhoi nga mea katoa, no reira ko te otinga whai hua ko te noho i te PTM me tetahi mea i te wa e whiwhi ana nga raraunga mai i a IO.

Te haere tonu i te kupu whakarite:

  • Mena kei te whakarite i te omelet, ka ngana ano ahau ki te huri kakahu, he tauira tenei mo te mahi maha. He ahua nui: he pai ake nga rorohiko ki tenei i nga tangata.
  • He kīhini me te maha o nga kaitao, hei tauira i roto i te wharekai - he rorohiko maha-matua.
  • He maha nga wharekai i roto i te kooti kai i roto i te pokapu hokohoko - pokapū raraunga

Utauta .NET

He pai a NET ki te mahi me nga miro, pera me era atu mea maha. Ma ia putanga hou, he maha ake nga taputapu hou mo te mahi ki a raatau, he paparanga hou o te tangohanga i runga i nga miro OS. I te wa e mahi ana ki te hanga tangohanga, ka whakamahia e nga kaiwhakawhanake anga he huarahi ka waiho te whai waahi, i te wa e whakamahi ana i te tangohanga taumata-tiketike, ki te heke iho kia kotahi, neke atu ranei nga taumata ki raro. Ko te nuinga o nga wa kaore tenei e tika ana, me te mea ka whakatuwherahia e ia te tatau ki te pupuhi i a koe i roto i te waewae me te pupuhi, engari i etahi wa, i nga keehi onge, koinei anake te huarahi hei whakaoti rapanga kaore i te whakatauhia i te taumata tangohanga o naianei. .

Ko nga taputapu, ko taku tikanga e rua nga atanga papatono tono (API) e whakaratohia ana e te anga me nga kohinga tuatoru, me nga otinga rorohiko katoa e ngawari ana te rapu mo nga raru e pa ana ki te waehere miro-maha.

Ka timata i te miro

Ko te akomanga Miro te tino karaehe taketake i roto i te .NET mo te mahi me nga miro. Ka whakaaetia e te kaihanga tetahi o nga kaikawe e rua:

  • ThreadStart — Kaore he tawhā
  • ParametrizedThreadStart - me tetahi tawhā o te momo ahanoa.

Ka mahia te kaikawe i roto i te miro hou i hangaia i muri i te karangatanga i te aratuka Tīmata. Ki te tukuna he kaitakawaenga momo ParametrizedThreadStart ki te kaihanga, me tuku he ahanoa ki te tikanga Tīmata. Ka hiahiatia tenei tikanga hei whakawhiti i nga korero o te rohe ki te awa. He mea tika kia mohio ko te hanga i te miro he mahi utu nui, a ko te miro ano he mea taumaha, na te mea ka tohatohahia te 1MB o te mahara ki runga i te puranga me te hiahia ki te taunekeneke me te OS API.

new Thread(...).Start(...);

Ko te akomanga ThreadPool e tohu ana i te kaupapa o te puna. I roto i te .NET, he mahi miihini te puna miro, a kua whakapau kaha nga kaiwhakawhanake i Microsoft ki te whakarite kia pai te mahi i roto i nga momo ahuatanga.

Ariā whānui:

Mai i te wa i timata ai te tono, ka hangaia e ia etahi miro kua rahuitia ki te papamuri me te whai waahi ki te tango hei whakamahi. Mena ka whakamahia nga miro i nga wa maha me te nui, ka whakawhānuihia te puna ki te whakatutuki i nga hiahia o te kaikaranga. Mena karekau he miro kore utu i roto i te poka wai i te wa tika, ka tatari mo tetahi o nga miro kia hoki mai, ka hangaia ranei he miro hou. Ka whai ake he pai te puna miro mo etahi mahi mo te wa poto me te kore e pai mo nga mahi e whakahaere ana hei ratonga puta noa i te mahinga katoa o te tono.

Hei whakamahi i tetahi miro mai i te puna, he tikanga QueueUserWorkItem e whakaae ana ki te kaitakawaenga o te momo WaitCallback, he rite tonu te waitohu ki te ParametrizedThreadStart, a ko te tawhā ka tukuna ki a ia he rite te mahi.

ThreadPool.QueueUserWorkItem(...);

Ko te tikanga poka wai miro iti-mohiotia ko RegisterWaitForSingleObject ka whakamahia hei whakarite i nga mahi IO kore-aukati. Ko te kaikawe i tukuna ki tenei tikanga ka karangahia ina tukuna te WaitHandle ki te tikanga ko "Whakaputaina".

ThreadPool.RegisterWaitForSingleObject(...)

.NET he matama miro, he rereke mai i nga matawā WinForms/WPF i te mea ka karangahia tana kaikawe i runga i te miro i tangohia mai i te puna.

System.Threading.Timer

He huarahi kee ano ki te tuku i tetahi kaikawe mo te mahi ki tetahi miro mai i te puna - te tikanga BeginInvoke.

DelegateInstance.BeginInvoke

E hiahia ana ahau ki te noho poto ki runga i te mahi e kiia ai te maha o nga tikanga o runga ake nei - CreateThread from Kernel32.dll Win32 API. He huarahi, he mihi ki nga tikanga o waho, ki te karanga i tenei mahi. Kua kite ahau i taua piiraa mo te wa kotahi i roto i tetahi tauira whakamataku o te waehere tuku iho, a ko te hihiri o te kaituhi nana i penei te mahi he mea ngaro tonu ki ahau.

Kernel32.dll CreateThread

Tirohanga me te patuiro i nga Miro

Ko nga miro i hangaia e koe, nga waahanga tuatoru katoa, me te puna .NET ka taea te tiro ki te matapihi Miro o Visual Studio. Ka whakaatu noa tenei matapihi i nga korero miro ina kei raro te tono i te patuiro me te aratau Whati. I konei ka taea e koe te maataki i nga ingoa puranga me nga kaupapa matua o ia miro, ka huri i te patuiro ki tetahi miro motuhake. Ma te whakamahi i te taonga Matua o te akomanga Miro, ka taea e koe te whakarite i te kaupapa matua o te miro, ka kitea e te OC me te CLR hei kupu tohutohu ina wehea te wa tukatuka i waenga i nga miro.

.NET: Utauta mo te mahi me te miro maha me te tukutahi. Wāhanga 1

Whare Pukapuka Whakarara Mahi

I whakaurua te Task Parallel Library (TPL) ki .NET 4.0. Inaianei ko te paerewa me te taputapu matua mo te mahi me te asynchrony. Ko nga waehere e whakamahi ana i te huarahi tawhito ka kiia he taonga tuku iho. Ko te waeine taketake o TPL ko te akomanga Taumahi mai i te mokowāingoa Pūnaha.Threading.Tasks. Ko te mahi he tangohanga i runga i te miro. Na te putanga hou o te reo C#, he huarahi huatau te mahi me nga Mahi - async/await operators. Na enei ariā i taea ai te tuhi i te waehere tukutahi me te mea he ngawari me te tukutahi, na tenei ka taea e nga tangata iti te mohio ki nga mahi o roto o nga miro ki te tuhi i nga tono e whakamahi ana, nga tono e kore e whakatio i te wa e mahi ana i nga mahi roa. Ko te whakamahi i te async/wait he kaupapa mo te kotahi, he maha ranei nga tuhinga, engari ka ngana ahau ki te tiki i te ngako o roto i etahi rerenga korero:

  • Ko te async he whakarerekētanga o te tikanga whakahoki i te Tūmahi, kua kore ranei
  • a ko te tatari he kaiwhakahaere mahi tatari kore-aukati.

Ano ano: ko te kaiwhakahaere tatari, i roto i te keehi whanui (he rerekee), ka tukuna ano te miro o naianei o te mahi, a ka mutu te mahi a te Mahi, me te miro (he pono, he tika ake te korero i te horopaki. , engari he nui ake i muri mai) ka mahi tonu i te tikanga. I roto i te .NET, he rite tonu te whakatinanatanga o tenei tikanga ki te hokinga mai, ka huri te tikanga tuhi ki te karaehe katoa, he mihini kawanatanga ka taea te mahi i roto i nga waahanga motuhake i runga i enei ahuatanga. Ka taea e te hunga e hiahia ana te tuhi i tetahi waehere ngawari ma te whakamahi i te asynс/await, te whakahiato me te tiro i te huihuinga ma te whakamahi i te JetBrains dotPeek me te Waehere Hanga Kaihanga kua whakahohea.

Me titiro ki nga whiringa mo te whakarewatanga me te whakamahi i te Mahi. I roto i te tauira waehere i raro nei, ka hangaia e matou he mahi hou e kore e whai hua (Miro.Moe(10000)), engari i roto i te ora tonu, me mahi he mahi uaua PTM.

using TCO = System.Threading.Tasks.TaskCreationOptions;

public static async void VoidAsyncMethod() {
    var cancellationSource = new CancellationTokenSource();

    await Task.Factory.StartNew(
        // Code of action will be executed on other context
        () => Thread.Sleep(10000),
        cancellationSource.Token,
        TCO.LongRunning | TCO.AttachedToParent | TCO.PreferFairness,
        scheduler
    );

    //  Code after await will be executed on captured context
}

Ka hangaia he Mahi me te maha o nga whiringa:

  • Ko te LongRunning he tohu e kore e oti tere te mahi, ko te tikanga he mea pai kia kaua e tango i tetahi miro mai i te puna wai, engari me hanga he mahi motuhake mo tenei Mahi kia kore ai e kino etahi atu.
  • AttachedToParent - Ka taea te whakarite i nga mahi i roto i te rarangi arowhai. Mēnā i whakamahia tēnei kōwhiringa, ka noho pea te Tūmahi i te āhua kua oti i a ia ano, kei te tatari mo te whakamatenga o ana tamariki.
  • PreferFairness - ko te tikanga he pai ake te mahi i nga Mahi i tukuna mo te mahi i mua atu i era ka tukuna i muri mai. Engari he taunakitanga noa tenei, a, kaore nga hua e taurangitia.

Ko te tawhā tuarua i tukuna ki te tikanga ko te WhakakoreToken. Kia tika ai te whakahaere i te whakakorenga o tetahi mahi i muri i te tiimatanga, me whakakiia te waehere e mahia ana ki nga haki mo te ahua WhakakorengaToken. Mena karekau he arowhai, na te tikanga Whakakore e kiia ana i runga i te ahanoa WhakakoreTokenSource ka taea te aukati i te mahinga o te Mahi i mua i te tiimata.

Ko te tawhā whakamutunga he ahanoa whakahōtaka o te momo KaihōtakaTumahi. I hoahoatia tenei karaehe me ona uri ki te whakahaere rautaki mo te tohatoha i nga Mahi puta noa i nga miro; ma te taunoa, ka mahia te Mahi i runga i te miro matapōkere mai i te puna.

Ko te kaiwhakahaere tatari ka tukuna ki te Mahi i hangaia, ko te tikanga ko te waehere i tuhia i muri mai, mena he kotahi, ka mahia i roto i te horopaki rite (he maha tonu te tikanga i runga i te miro kotahi) me te waehere i mua i te tatari.

Ko te tikanga kua tohua he async void, ko te tikanga ka taea e ia te whakamahi i te kaiwhakahaere tatari, engari kaore e taea e te waehere waea te tatari mo te mahi. Mena e tika ana taua ahuatanga, me whakahoki ano te tikanga i te Mahi. Ko nga tikanga e tohuhia ana ko te async void he mea noa: hei tikanga, he kaikawe huihuinga enei, etahi atu tikanga ranei e mahi ana i te ahi ka wareware i te kaupapa. Mena ka hiahia koe kia kaua e hoatu he waahi ki te tatari tae noa ki te mutunga o te mahi, engari ka whakahoki ano i te hua, ka hiahia koe ki te whakamahi i te Mahi.

I runga i te Mahi i hoki mai te tikanga StartNew, me etahi atu, ka taea e koe te karanga i te tikanga ConfigureAwait me te tawhā teka, katahi ka haere tonu te mahi i muri i te tatari kaore i runga i te horopaki kua hopukina, engari i runga i te mea noa. Me mahi tenei i nga wa katoa kaore he mea nui te horopaki mahi mo te waehere i muri i te tatari. He taunakitanga ano tenei na MS i te wa e tuhi ana i te waehere ka tukuna ki roto i te whare pukapuka.

Me noho ake ano me pehea koe e tatari ai mo te otinga o tetahi Mahi. Kei raro nei he tauira o te waehere, me nga korero mo te wa e mahia paitia ana te tumanako me te wa e mahia kino ana.

public static async void AnotherMethod() {

    int result = await AsyncMethod(); // good

    result = AsyncMethod().Result; // bad

    AsyncMethod().Wait(); // bad

    IEnumerable<Task> tasks = new Task[] {
        AsyncMethod(), OtherAsyncMethod()
    };

    await Task.WhenAll(tasks); // good
    await Task.WhenAny(tasks); // good

    Task.WaitAll(tasks.ToArray()); // bad
}

I te tauira tuatahi, ka tatari tatou kia oti te Mahi me te kore e aukati i te miro waea; ka hoki ano tatou ki te tukatuka i te hua ka tae noa ki reira; tae noa ki tera wa, ka waiho te miro waea ki ona ake whakaaro.

I te rua o nga whiringa, ka aukatihia e matou te miro karanga tae noa ki te tatau i te hua o te tikanga. He kino tenei ehara i te mea kua noho tatou i tetahi miro, he rauemi tino nui o te kaupapa, me te mangere noa, engari na te mea kei te tatari te waehere o te tikanga e kiia nei e matou, a ko te horopaki tukutahi me hoki ki te miro karanga i muri mai. tatari, katahi ka whiwhi tatou i te mate: Ka tatari te miro karanga kia tatauhia te hua o te tikanga tukutahi, ka ngana noa te tikanga tukutahi ki te haere tonu i tana mahi ki te miro karanga.

Ko tetahi atu kino o tenei huarahi ko te whakahaere hapa uaua. Ko te meka ko nga hapa i roto i te waehere tukutahi i te wa e whakamahi ana i te async/tatari he tino ngawari ki te hapai - he rite tonu te mahi me te mea he tukutahi te waehere. Ahakoa ki te tono tatou i te whakataki tatari tukutahi ki tetahi Mahi, ka huri te otahi taketake ki te AggregateException, ara. Ki te hapai i te tuunga, me tirotiro koe i te momo InnerException me te tuhi i tetahi mekameka ki roto i tetahi poraka hopu, whakamahi ranei i te hopu i te wa e hanga ana, kaua ki te mekameka o nga poraka hopu e mohio ake ana i te ao C#.

Ko nga tauira tuatoru me nga tauira whakamutunga ka tohua he kino mo te take kotahi me nga raru katoa kei roto.

Ko nga tikanga WhenAny me WhenAll he tino watea mo te tatari mo te roopu o nga Mahi; ka takai ratou i te roopu o nga Mahi ki te kotahi, ka puhipuhi i te wa tuatahi ka puta te mahi mai i te roopu, ka oti ranei te katoa o te mahi.

Kati miro

He maha nga take, me whakamutu te rere i muri i te tiimatanga. He maha nga huarahi hei mahi i tenei. E rua nga tikanga whakaingoa tika i te akomanga Miro: Taapiri и haukoti. Ko te mea tuatahi kaore i te tino tūtohutia mo te whakamahi, na te mea i muri i te karanga i tetahi wa ohorere, i te wa e tukatuka ana i tetahi tohutohu, ka tukuna he rereke ThreadAbortedException. Kare koe e whakaaro ka makahia he rerekee ina whakanuia tetahi taurangi tauoti, tika? A, ka whakamahi i tenei tikanga, he tino ahuatanga tenei. Mena ka hiahia koe ki te aukati i te CLR kia kore e whakaputa i taua tuunga ki tetahi waahanga o te waehere, ka taea e koe te takai ki nga waea. Miro.BeginCriticalRegion, Miro.EndCriticalRegion. Ko nga waehere kua tuhia ki roto i te poraka mutunga ka takai ki nga waea pera. Mo konei, i roto i te hohonutanga o te waehere anga ka kitea e koe nga poraka me te ngana kau, engari karekau he kau. Ka tino whakararu a Microsoft i tenei tikanga kaore i whakauruhia ki roto i te .net matua.

He pai ake te mahi a te aratuka Interrupt. Ka taea e ia te haukoti i te miro me te rereke ThreadInterruptedException i nga wa anake e tatari ana te miro. Ka uru ki tenei ahua i te wa e iri ana i te wa e tatari ana mo WaitHandle, maukati, i muri ranei i te waeatanga ki a Thread.Sleep.

Ko nga whiringa e rua e whakaahuatia ana i runga ake nei he kino na te kore ohorere. Ko te otinga ko te whakamahi hanganga WhakakoreToken me te akomanga WhakakoreTokenSource. Ko te take ko tenei: he tauira o te karaehe WhakakoreTokenSource ka hangaia a ko te tangata nona anake ka taea te aukati i te mahi ma te karanga i te tikanga Whakakore. Ko te WhakakoreToken anake ka tukuna ki te mahi tonu. Kaore e taea e nga rangatira o te WhakakoreToken te whakakore i te mahi, engari ka taea anake te tirotiro mena kua whakakorehia te mahi. He taonga Boolean mo tenei Kua Tonoa te Whakakore me te tikanga ThrowIfCancelRequested. Ko te whakamutunga ka maka he okotahi TaumahiWhakakoreWhakaaetanga mena i karangahia te tikanga Whakakore i runga i te tauira WhakakoreToken e parea ana. A koinei te tikanga ka tūtohu ahau ki te whakamahi. He pai ake tenei ki nga whiringa o mua ma te whai mana katoa mo te waahi ka taea te whakakore i tetahi mahi motuhake.

Ko te whiringa tino kino mo te aukati i te miro ko te karanga i te mahi Win32 API TerminateThread. Ko te whanonga o te CLR i muri i te karangatanga o tenei mahi karekau pea e kitea. I runga i te MSDN ka tuhia e whai ake nei mo tenei mahi: "Ko te TerminateThread he mahi kino e tika ana kia whakamahia i roto i nga keehi tino kino. “

Te huri i te API tuku iho ki te Mahi Ma te whakamahi i te tikanga FromAsync

Mena kei te waimarie koe ki te mahi i tetahi kaupapa i timatahia i muri i te whakaurunga o nga Mahi me te whakamutu i te whakamataku marie mo te nuinga o nga kaiwhakawhanake, katahi ka kore koe e pa ki te maha o nga API tawhito, te hunga tuatoru me era o to roopu. kua whakamamaetia i mua. Waimarie, na te roopu .NET Framework matou i tiaki, ahakoa pea ko te whainga ki te tiaki i a matou ano. Ahakoa tera pea, he maha nga taputapu a NET mo te huri noa i te waehere kua tuhia ki roto i nga huarahi whakahoahoa tukutahi tawhito ki te mea hou. Ko tetahi o ratou ko te tikanga FromAsync o TaskFactory. I roto i te tauira waehere i raro nei, ka takai ahau i nga tikanga async tawhito o te akomanga WebRequest i roto i tetahi Mahi ma te whakamahi i tenei tikanga.

object state = null;
WebRequest wr = WebRequest.CreateHttp("http://github.com");
await Task.Factory.FromAsync(
    wr.BeginGetResponse,
    we.EndGetResponse
);

He tauira noa tenei, kaore pea koe e mahi me nga momo hanga-i roto, engari ko nga kaupapa tawhito kei te kapi noa i nga tikanga BeginDoSomething e whakahoki ana i nga tikanga IAsyncResult me ​​EndDoSomething ka whiwhi.

Tahurihia te API tuku iho ki te mahi i runga i te mahi ma te whakamahi i te akomanga TaskCompletionSource

Ko tetahi atu taputapu nui hei whakaaro ko te akomanga Pūtake Whakaoti Mahi. Mo nga mahi, te kaupapa me te maapono o te mahi, he ahua maumahara pea ki te tikanga RegisterWaitForSingleObject o te akomanga ThreadPool, i tuhia e au mo runga ake nei. Ma te whakamahi i tenei karaehe, ka taea e koe te takai i nga API tukutahi tawhito ki nga Mahi.

Ka kii koe kua korero kee au mo te tikanga FromAsync o te akomanga TaskFactory mo enei kaupapa. I konei me mahara tatou ki te hitori katoa o te whanaketanga o nga tauira tukutahi i roto i te .net i tukuna e Microsoft i nga tau 15 kua hipa: i mua i te Tauira Asynchronous Asynchronous (TAP), i reira ko te Tauira Papatono Asynchronous (APP), e mo nga tikanga TīmataKei te hoki mai tetahi mea IAsyncResult me nga tikanga whakamutungaDoSomething e whakaae ana, mo nga taonga tuku iho o enei tau he tino tika te tikanga FromAsync, engari i te roanga o te waa, ka whakakapihia e te Tauira Asynchronous Kaupapa Takahanga (EAP), i whakaaro ka ara ake he takahanga ina oti te mahi tukutahi.

He tino pai te TaskCompletionSource mo te takai i nga Mahi me nga API tuku iho i hangaia huri noa i te tauira takahanga. Ko te ngako o ana mahi e whai ake nei: ko tetahi mea o tenei karaehe he taonga mo te iwi mo te momo Tumahi, ka taea te whakahaere i tona ahua ma nga tikanga SetResult, SetException, aha atu o te akomanga TaskCompletionSource. I nga waahi i tonohia te kaiwhakahaere tatari ki tenei Tumahi, ka mahia, ka kore ranei me te rereke i runga i te tikanga i hoatu ki te TaskCompletionSource. Mena kare tonu i te marama, me titiro ki tenei tauira waehere, kei reira etahi EAP API tawhito e takai ana ki roto i te Tumahi ma te whakamahi i te TaskCompletionSource: ka pa ana te huihuinga, ka tuu te Tumahi ki te ahua Kua oti, me te tikanga i tono te kaiwhakahaere tatari. ki tenei Tūmahi ka mahi ano i te mea kua riro mai te ahanoa hua.

public static Task<Result> DoAsync(this SomeApiInstance someApiObj) {

    var completionSource = new TaskCompletionSource<Result>();
    someApiObj.Done += 
        result => completionSource.SetResult(result);
    someApiObj.Do();

    result completionSource.Task;
}

TaumahiWhakaotiSource Tips & Tricks

Ko te takai i nga API tawhito ehara i te mea ka taea te whakamahi ma te TaskCompletionSource. Ma te whakamahi i tenei karaehe ka tuwhera te ahua pai ki te hoahoa i nga momo API mo nga Mahi karekau e noho ki nga miro. A ko te awa, e mahara ana matou, he rauemi utu nui, he iti noa to raatau nama (te nuinga o te rahi o te RAM). Ka taea te whakatutuki ngawari tenei herenga ma te whakawhanake, hei tauira, he tono tukutuku kua utaina me te arorau pakihi uaua. Kia whai whakaaro tatou ki nga mea ka taea e au e korero ana i te wa e whakatinanahia ana he tinihanga penei i te Roo-Pooti.

I roto i te poto, ko te tino o te tinihanga ko tenei: me whiwhi koe i nga korero mai i te API mo etahi huihuinga e puta ana i tona taha, ko te API, mo etahi take, kaore e taea te whakaatu i te huihuinga, engari ka taea anake te whakahoki i te kawanatanga. Ko tetahi tauira o enei ko nga API katoa i hangaia i runga i te HTTP i mua i nga wa o WebSocket, i te wa kaore e taea te whakamahi i tenei hangarau. Ka taea e te kiritaki te patai ki te tūmau HTTP. Kaore e taea e te tūmau HTTP te korero ki te kiritaki. Ko te otinga ngawari ko te pooti i te kaimau ma te whakamahi i te taima, engari ka nui ake te utaina ki runga i te tūmau me te whakaroa atu i te Waawaenga Waewaewae / 2. Hei whakatika i tenei, i hangahia he tinihanga e kiia nei ko te Pooti Roa, ko te whakaroa i te whakautu mai i te tūmau tae noa ki te paunga o te Wāwā ka puta he takahanga. Mena kua puta te kaupapa, ka tukatukahia, ki te kore, ka tukuna ano te tono.

while(!eventOccures && !timeoutExceeded)  {

  CheckTimout();
  CheckEvent();
  Thread.Sleep(1);
}

Engari ko tenei otinga ka tino whakamataku i te wa ka piki ake te maha o nga kaihoko e tatari ana mo te huihuinga, na te mea ... Kei ia kiritaki he miro katoa e tatari ana mo tetahi huihuinga. Ae, ka whiwhi tatou i te roanga 1ms i te wa e whakaohohia ana te huihuinga, i te nuinga o te waa kaore tenei i te mea nui, engari he aha te take ka kino ake ai te rorohiko? Mena ka tangohia e tatou te Miro.Sleep(1), ka kore noa ka utaina e tatou tetahi matua tukatuka 100% mangere, ka huri i roto i te huringa koretake. Ma te whakamahi i te TaskCompletionSource ka taea e koe te whakarereke i tenei waehere me te whakaoti i nga raru katoa kua tohua i runga ake nei:

class LongPollingApi {

    private Dictionary<int, TaskCompletionSource<Msg>> tasks;

    public async Task<Msg> AcceptMessageAsync(int userId, int duration) {

        var cs = new TaskCompletionSource<Msg>();
        tasks[userId] = cs;
        await Task.WhenAny(Task.Delay(duration), cs.Task);
        return cs.Task.IsCompleted ? cs.Task.Result : null;
    }

    public void SendMessage(int userId, Msg m) {

        if (tasks.TryGetValue(userId, out var completionSource))
            completionSource.SetResult(m);
    }
}

Ehara tenei waehere i te hanga-rite, engari he whakaaturanga noa. Hei whakamahi i roto i nga keehi pono, me hiahia ano koe, i te iti rawa, ki te whakahaere i te ahuatanga ka tae mai he karere i te wa kaore he tangata e tatari ana: i tenei keehi, me whakahoki te tikanga AsseptMessageAsync i tetahi Mahi kua oti. Mena koinei te keehi tino noa, ka taea e koe te whakaaro mo te whakamahi ValueTask.

Ka tae mai he tono mo te karere, ka waihangahia, ka tuuhia he TaskCompletionSource ki roto i te papakupu, ka tatari mo te mea ka puta tuatahi: ka pau te wa kua tohua, ka tae mai ranei he karere.

ValueTask: he aha me pehea

Ko nga kaiwhakahaere async / tatari, penei i te kaiwhakahaere whakahoki hua, ka whakaputa i te miihini kawanatanga mai i te tikanga, a koinei te hanganga o tetahi mea hou, he tata tonu kaore he mea nui, engari i nga wa onge ka taea e ia te raru. Ko tenei keehi pea he tikanga e kiia ana he maha nga wa, e korero ana matou mo nga tekau me nga rau mano o nga waea mo ia hekona. Mena ka tuhia he tikanga penei i te nuinga o te waa ka hoki mai he hua ka hipa i nga tikanga tatari katoa, ka tukuna e .NET tetahi taputapu hei arotau i tenei - te hanganga ValueTask. Kia marama ai, me titiro ki tetahi tauira o tona whakamahinga: he keteroki e haere pinepine ana tatou. He uara kei roto, ka whakahokia noa atu; ki te kore, katahi ka haere ki etahi IO puhoi ki te tiki. Kei te pirangi au ki te mahi i nga mea o muri mai i te tukutahi, ko te tikanga ka huri te tikanga katoa ki te kore tukutahi. No reira, ko te huarahi marama ki te tuhi i te tikanga e whai ake nei:

public async Task<string> GetById(int id) {

    if (cache.TryGetValue(id, out string val))
        return val;
    return await RequestById(id);
}

Na te hiahia ki te arotau iti, me te iti o te mataku ki ta Roslyn e whakaputa i te wa e whakahiato ana i tenei waehere, ka taea e koe te tuhi ano i tenei tauira penei:

public Task<string> GetById(int id) {

    if (cache.TryGetValue(id, out string val))
        return Task.FromResult(val);
    return RequestById(id);
}

Ae ra, ko te otinga tino pai mo tenei keehi ko te arotau i te huarahi wera, ara, te whiwhi uara mai i te papakupu me te kore he tohatoha me te utaina ki runga i te GC, i nga keehi onge ka hiahia tonu tatou ki te haere ki IO mo nga raraunga. , ka noho tonu nga mea katoa hei taapiri / whakaheke i te huarahi tawhito:

public ValueTask<string> GetById(int id) {

    if (cache.TryGetValue(id, out string val))
        return new ValueTask<string>(val);
    return new ValueTask<string>(RequestById(id));
}

Kia ata titiro tatou ki tenei wahanga o te waehere: mena he uara kei roto i te keteroki, ka hangaia he hanganga, ki te kore ka takaia te mahi tuturu ki tetahi mahi whai kiko. Karekau te tohu waea e aro ko tehea ara i mahia ai tenei waehere: ValueTask, mai i te tirohanga whakahiato C#, ka rite te mahi ki tetahi Mahi i tenei keehi.

Kaiwhakarite Mahi: te whakahaere i nga rautaki whakarewa mahi

Ko te API e whai ake nei e hiahia ana ahau ki te whakaaro ko te akomanga Kaihōtaka Mahi me ona putanga. Kua korerohia e au i runga ake nei kei a TPL te kaha ki te whakahaere rautaki mo te tohatoha i nga Mahi puta noa i nga miro. Ko enei momo rautaki kua tautuhia i roto i nga uri o te akomanga TaskScheduler. Tata ki nga rautaki e hiahia ana koe ka kitea i te whare pukapuka. ParallelExtensionsExtras, i whakawhanakehia e Microsoft, engari ehara i te waahanga o .NET, engari i tukuna hei kete Nuget. Ka titiro poto tatou ki etahi o ratou:

  • KaihokoTumahiMiro o naianei — ka mahia nga Mahi i runga i te miro o naianei
  • LimitedConcurrencyLevelTaskScheduler — whakawhāitihia te maha o nga Mahi ka mahia i te wa kotahi ma te tawhā N, ka whakaaetia i roto i te kaihanga.
  • OrderedTaskScheduler — kua tautuhia hei LimitedConcurrencyLevelTaskScheduler(1), no reira ka mahia nga mahi a-raupapa.
  • WorkStealingTaskScheduler - taputapu tahae mahi huarahi ki te tohatoha mahi. Ko te tikanga he ThreadPool motuhake. Ka whakatau i te raruraru kei roto i te .NET ThreadPool he karaehe pateko, kotahi mo nga tono katoa, ko te tikanga ko te taumahatanga, te he ranei o te whakamahi i tetahi waahanga o te papatono ka pa ki etahi atu. I tua atu, he tino uaua ki te mohio ki te take o enei hapa. Ko tera. Ka hiahia pea ki te whakamahi i nga WorkStealingTaskSchedulers motuhake i roto i nga waahanga o te hotaka kei te kaha te whakamahi i te ThreadPool me te kore ohorere.
  • QeuedTaskScheduler — ka taea e koe te mahi i nga mahi i runga i nga ture rarangi matua
  • ThreadPerTaskScheduler — ka hangaia he miro motuhake mo ia Mahi ka mahia ki runga. Ka whai hua mo nga mahi ka roa te roa ka oti.

He pai nga korero taipitopito tuhinga e pā ana ki ngā Pūwhakatakamahi i runga i te blog microsoft.

Mo te pai o te whakakore i nga mea katoa e pa ana ki nga Mahi, he matapihi Mahi a Visual Studio. I tenei matapihi ka kite koe i te ahuatanga o naianei o te mahi ka peke atu ki te rarangi waehere e mahi ana i tenei wa.

.NET: Utauta mo te mahi me te miro maha me te tukutahi. Wāhanga 1

PLinq me te karaehe Whakarara

I tua atu i nga Mahi me nga mea katoa i korero mo ratou, e rua ano nga taputapu whakamere i roto i te .NET: PLinq (Linq2Parallel) me te akomanga Whakarara. Ko te tuatahi ka oati kia rite nga mahi katoa a Linq i runga i nga miro maha. Ka taea te whirihora i te maha o nga miro ma te whakamahi i te tikanga toronga WithDegreeOfParallelism. Engari, ko te nuinga o nga wa karekau he nui o nga korero a PLinq i roto i tana aratau taunoa e pa ana ki nga waahanga o roto o to puna raraunga hei whakarato i te tere tere, engari he iti rawa te utu o te ngana: me waea noa koe ki te tikanga AsParallel i mua te mekameka o nga tikanga Linq me te whakahaere i nga whakamatautau mahi. I tua atu, ka taea te tuku atu korero ki a PLinq mo te ahua o to puna raraunga ma te whakamahi i te tikanga Wehewehenga. Ka taea e koe te panui atu konei и konei.

Ka whakaratohia e te karaehe pateko Whakarara nga tikanga mo te whakarara i roto i te kohinga Foreach i roto i te whakarara, te mahi i te Mo te kapiti, me te whakahaere i nga kaikawe maha i roto i te Invoke whakarara. Ka mutu te mahi o te miro o naianei kia oti ra ano nga tatauranga. Ka taea te whirihora te maha o nga miro ma te tuku ParallelOptions hei tohenga whakamutunga. Ka taea hoki e koe te tautuhi i te KaimahiTumahi me te WhakakoreToken ma te whakamahi i nga whiringa.

kitenga

I taku tiimata ki te tuhi i tenei tuhinga i runga i nga rauemi o taku ripoata me nga korero i kohia e au i aku mahi i muri mai, kare au i whakaaro ka nui noa atu. Inaianei, ka kii mai te etita tuhinga e tuhi nei ahau i tenei tuhinga kua ngaro te wharangi 15, ka whakarapopototia e au nga hua mo te wa poto. Ko etahi atu tinihanga, API, taputapu ataata me nga mahanga ka hipokina ki te tuhinga e whai ake nei.

Whakamutunga:

  • Me mohio koe ki nga taputapu mo te mahi me nga miro, te tukutahi me te whakarara hei whakamahi i nga rauemi o nga PC hou.
  • He maha nga taputapu rereke a NET mo enei kaupapa
  • Kaore katoa i puta i te wa kotahi, no reira ka kitea e koe nga mea tuku iho, heoi, he huarahi ki te huri i nga API tawhito me te kore e whakapau kaha.
  • Ko te mahi me nga miro i .NET e tohuhia ana e nga akomanga Miro me te ThreadPool
  • Ko nga tikanga Thread.Abort, Thread.Interrupt, me Win32 API TerminateThread he mea kino, kaore i te tūtohutia kia whakamahia. Engari, he pai ake te whakamahi i te tikanga WhakakoreToken
  • He tino rawa te rere, he iti te tuku. Ko nga ahuatanga kei te pukumahi nga miro e tatari ana mo nga huihuinga me karohia. Mo tenei he pai ki te whakamahi i te akomanga TaskCompletionSource
  • Ko nga taputapu .NET tino kaha me te matatau mo te mahi me te whakarara me te tukutahi ko nga Mahi.
  • Ka whakatinanahia e nga kaiwhakahaere c# async/await te ariā o te tatari kore-aukati
  • Ka taea e koe te whakahaere i te tohatoha o nga Mahi puta noa i nga miro ma te whakamahi i nga karaehe i ahu mai i a TaskScheduler
  • Ka whai hua te hanganga ValueTask ki te arotau i nga ara-wera me te waka mahara
  • Ko nga Matapihi Mahi me nga Miro a Visual Studio e whakarato ana i te maha o nga korero e whai hua ana mo te patuiro i te waehere miro-maha, i te waehere tukutahi ranei
  • He taputapu hauhautanga a PLinq, engari kaore pea i te nui nga korero mo to puna raraunga, engari ka taea te whakatika ma te whakamahi i te tikanga wehewehe.
  • Kia haere tonu ...

Source: will.com

Tāpiri i te kōrero