.NET: Lisebelisoa tsa ho sebetsa ka multithreading le asynchrony. Karolo ea 1

Ke phatlalatsa sengoloa sa mantlha ka Habr, seo phetolelo ea sona e kentsoeng k'hamphaning poso ea blog.

Tlhokahalo ea ho etsa ntho e 'ngoe ka mokhoa o ts'oanang, ntle le ho emela sephetho mona le hona joale, kapa ho arola mosebetsi o moholo har'a lihlopha tse' maloa tse e etsang, e ne e le teng pele ho hlaha lik'homphieutha. Ka ho fihla ha bona, tlhoko ena e ile ea bonahala haholo. Joale, ka selemo sa 2019, ke thaepa sengoloa sena ho laptop e nang le processor ea 8-core Intel Core, eo ho eona lits'ebetso tse fetang lekholo li tsamaeang ka ho ts'oana, esita le likhoele tse ngata. Haufi le moo, ho na le mohala o bobebe, o rekiloeng lilemong tse 'maloa tse fetileng, o na le processor ea 8-core ka sekepeng. Lisebelisoa tsa sehlooho li tletse lingoloa le livideo moo bangoli ba tsona ba khahloang ke li-smartphones tsa selemo sena tse nang le li-processor tsa 16-core. MS Azure e fana ka mochini o sebetsang o nang le processor ea mantlha ea 20 le RAM ea 128 TB ka tlase ho $2 / hora. Ka bomalimabe, ho ke ke ha khoneha ho ntša boholo le ho sebelisa matla ana ntle le ho khona ho laola ho sebelisana ha likhoele.

Terminology

Tshebetso - Ntho ea OS, sebaka se ikhethileng sa aterese, se na le likhoele.
Khoele - ntho ea OS, karolo e nyane ka ho fetisisa ea ts'ebetso, karolo ea ts'ebetso, likhoele li arolelana mohopolo le lisebelisoa tse ling ka har'a ts'ebetso.
Multitasking - Thepa ea OS, bokhoni ba ho tsamaisa lits'ebetso tse 'maloa ka nako e le ngoe
Multi-core - thepa ea processor, bokhoni ba ho sebelisa li-cores tse 'maloa bakeng sa ts'ebetso ea data
Multiprocessing - thepa ea k'homphieutha, bokhoni ba ho sebetsa ka nako e le 'ngoe le li-processor tse' maloa 'meleng
Multithreading - thepa ea ts'ebetso, bokhoni ba ho aba ts'ebetso ea data har'a likhoele tse 'maloa.
Ho bapisa - ho etsa diketso tse mmalwa ka nako e le nngwe
Asynchrony - ts'ebetso ea ts'ebetso ntle le ho emela ho phetheloa ha ts'ebetso ena; sephetho sa ts'ebetso se ka sebetsoa hamorao.

Setšoantšo sa puo

Ha se litlhaloso tsohle tse ntle 'me tse ling li hloka tlhaloso e eketsehileng, kahoo ke tla kenyelletsa papiso mabapi le ho pheha lijo tsa hoseng ho poleloana e hlahisitsoeng ka molao. Ho pheha lijo tsa hoseng ka papiso ena ke ts'ebetso.

Ha ke ntse ke lokisa lijo tsa hoseng hoseng ke (CPUKe tla kichineng (Khomphuta). Ke na le matsoho a mabeli (Li-cores). Ho na le lisebelisoa tse ngata ka kichineng (IO): onto, kettle, toaster, sehatsetsi. Ke hotetsa khase, ke beha pane e halikiloeng holim'a eona ebe ke tšela oli ho eona ntle le ho emela hore e chese (Asynchronously, Non-blocking-IO-Wait), ke ntša mahe ka sehatsetsing ebe ke a pshatla ka poleiti, ebe kea otla ka letsoho le le leng (Khoele#1), le ea bobeli (Khoele#2) ho tšoara poleiti (Mohlodi o Arohetsweng). Joale ke kopa ho bulela ketlele, empa ha ke na matsoho a lekaneng (Khoele Tlala) Nakong ena, pan ea frying e chesa (Ho sebetsa sephetho) moo ke tšelang seo ke se shahlileng. Ke nanabela ketlele ebe ke e bulela 'me ka booatla ke bona metsi a bela ho eona (Ho thibela-IO-Leta), le hoja nakong ena a ka be a ile a hlatsoa poleiti moo a neng a shapa omelet.

Ke phehile omelet ke sebelisa matsoho a mabeli feela, 'me ha ke na ho feta, empa ka nako e ts'oanang, nakong ea ho shapa omelette, ho ile ha etsoa opereishene tse 2 hang-hang: ho shapa omelette, ho tšoara poleiti, ho futhumatsa pane ea ho chesa. .CPU ke karolo e potlakileng ea komporo, IO ke seo hangata ntho e ngoe le e ngoe e liehang ho sebetsa, hangata tharollo e sebetsang ke ho kenya CPU ka ho hong ha o ntse o amohela data ho tsoa ho IO.

Ho tsoela pele ka mokhabo-puo:

  • Haeba nakong ea ho lokisetsa omelet, ke ne ke tla boela ke leke ho fetola liaparo, sena e ne e tla ba mohlala oa ho etsa lintho tse ngata. Ntho ea bohlokoa: lik'homphieutha li molemo haholo ho sena ho feta batho.
  • Kichine e nang le baapehi ba 'maloa, mohlala ka reschorenteng - k'homphieutha e nang le lisebelisoa tse ngata.
  • Lireschorente tse ngata lekhotleng la lijo sebakeng sa mabenkele - setsi sa data

Lisebelisoa tsa NET

.NET e sebetsa hantle ka likhoele, joalo ka lintho tse ling tse ngata. Ka mofuta o mong le o mong o mocha, e hlahisa lisebelisoa tse ncha le ho feta tsa ho sebetsa le tsona, likarolo tse ncha tsa ho ikhula holim'a likhoele tsa OS. Ha ba sebetsa le kaho ea li-abstractions, baetsi ba moralo ba sebelisa mokhoa o tlohelang monyetla, ha ba sebelisa ho tlosoa ha maemo a phahameng, ho theola boemo bo le bong kapa ho feta ka tlase. Hangata sena ha se hlokahale, ha e le hantle se bula monyako oa ho ithunya leotong ka sethunya, empa ka linako tse ling, maemong a sa tloaelehang, e ka 'na ea e-ba eona feela tsela ea ho rarolla bothata bo sa rarolloeng boemong ba hona joale ba ho tlosoa. .

Ka lisebelisoa, ke bolela li-interfaces tsa li-application programming (APIs) tse fanoeng ke moralo le liphutheloana tsa batho ba boraro, hammoho le tharollo ea software eohle e nolofatsang ho batla mathata leha e le afe a amanang le khoutu e mengata.

Ho qala khoele

The Thread class is the most basic class in .NET bakeng sa ho sebetsa ka likhoele. Moetsi o amohela e mong oa baemeli ba babeli:

  • ThreadStart - Ha ho li-parameter
  • ParametrizedThreadStart - e nang le parameter e le 'ngoe ea mofuta oa ntho.

Moemeli o tla phethisoa khoeleng e sa tsoa etsoa ka mor'a ho letsetsa mokhoa oa Qala.Haeba moemeli oa mofuta oa ParametrizedThreadStart a fetiselitsoe ho moetsi, ntho e tlameha ho fetisetsoa ho mokhoa oa Qala. Mokhoa ona oa hlokahala ho fetisetsa tlhahisoleseding leha e le efe ea sebaka ho ea molapong. Ke habohlokoa ho hlokomela hore ho theha khoele ke ts'ebetso e theko e boima, 'me khoele ka boeona ke ntho e boima, bonyane hobane e fana ka 1MB ea mohopolo ho stack mme e hloka ho sebelisana le OS API.

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

Sehlopha sa ThreadPool se emela mohopolo oa letamo. Ho .NET, letamo la likhoele ke karolo ea boenjiniere, 'me bahlahisi ba Microsoft ba kentse boiteko bo matla ho etsa bonnete ba hore e sebetsa hantle maemong a mangata a fapaneng.

Khopolo e akaretsang:

Ho tloha ha kopo e qala, e theha likhoele tse 'maloa tse bolokiloeng ka morao mme e fana ka bokhoni ba ho li nka hore li sebelisoe. Haeba likhoele li sebelisoa khafetsa le ka bongata, letamo le atoloha ho fihlela litlhoko tsa motho ea letsetsang. Ha ho se na likhoele tsa mahala ka letamong ka nako e nepahetseng, e tla emela hore e 'ngoe ea likhoele e khutle, kapa e thehe e ncha. Ho latela hore khoele ea likhoele e ntle bakeng sa liketso tse ling tsa nako e khuts'oane ebile ha e tšoanelehe hantle bakeng sa lits'ebetso tse sebetsang joalo ka lits'ebeletso ts'ebetsong eohle ea kopo.

Ho sebelisa khoele e tsoang letamong, ho na le mokhoa oa QueueUserWorkItem o amohelang moemeli oa mofuta oa WaitCallback, o nang le mosaeno o tšoanang le oa ParametrizedThreadStart, mme paramethara e fetiselitsoeng ho eona e etsa mosebetsi o tšoanang.

ThreadPool.QueueUserWorkItem(...);

Mokhoa o sa tsejoeng haholo oa "thread pool" RegisterWaitForSingleObject o sebelisetsoa ho hlophisa tšebetso ea IO e sa thibeleng. Moemeli ea fetiselitsoeng ho mokhoa ona o tla bitsoa ha WaitHandle e fetisetsoa ho mokhoa "Ho lokolloa".

ThreadPool.RegisterWaitForSingleObject(...)

.NET e na le nako ea khoele 'me e fapane le li-timers tsa WinForms/WPF ka hore mohlokomeli oa eona o tla bitsoa khoele e nkiloeng letamong.

System.Threading.Timer

Ho boetse ho na le mokhoa o sa tloaelehang oa ho romela moemeli hore a bolaoe khoele e tsoang letamong - mokhoa oa BeginInvoke.

DelegateInstance.BeginInvoke

Ke kopa ho bua ka bokhutšoanyane ka mosebetsi oo mekhoa e mengata e ka holimo e ka bitsoang - CreateThread ho tloha Kernel32.dll Win32 API. Ho na le tsela, ka lebaka la mochine oa mekhoa ea ka ntle, ho bitsa mosebetsi ona. Ke bone pitso e joalo hanngoe feela mohlaleng o mobe oa khoutu ea lefa, mme khothatso ea mongoli ea entseng sena e ntse e le sephiri ho nna.

Kernel32.dll CreateThread

Ho shebella le ho lokisa likhoele

Likhoele tse entsoeng ke uena, likarolo tsohle tsa mokha oa boraro, le letamo la .NET li ka bonoa fensetereng ea Threads ea Visual Studio. Fesetere ena e tla bonts'a tlhahisoleseling feela ha ts'ebeliso e le tlas'a debug le ho Break mode. Mona o ka bona mabitso a stack le lintho tse tlang pele tsa khoele ka 'ngoe, 'me u fetole mokhoa oa ho lokisa liphoso ho khoele e itseng. U sebelisa thepa ea Bohlokoa ba sehlopha sa Thread, u ka beha bohlokoa ba khoele, eo OC le CLR li tla e nka e le khothaletso ha u arola nako ea processor lipakeng tsa likhoele.

.NET: Lisebelisoa tsa ho sebetsa ka multithreading le asynchrony. Karolo ea 1

Laebrari ea Mosebetsi oa Parallel

Task Parallel Library (TPL) e ile ea hlahisoa ho .NET 4.0. Hona joale ke sesebelisoa se tloaelehileng le se ka sehloohong sa ho sebetsa le asynchrony. Khoutu efe kapa efe e sebelisang mokhoa oa khale e nkuoa e le lefa. Karolo ea mantlha ea TPL ke Sehlopha sa Mosebetsi ho tsoa ho System.Threading.Tasks namespace. Mosebetsi ke tlhaloso e akaretsang holim'a khoele. Ka mofuta o mocha oa puo ea C #, re na le mokhoa o motle oa ho sebetsa le Tasks - async/wait operators. Likhopolo tsena li entse hore ho khonehe ho ngola khoutu ea asynchronous joalokaha eka e bonolo ebile e lumellana, sena se ile sa etsa hore ho khonehe le batho ba nang le kutloisiso e fokolang ea ts'ebetso ea ka hare ea likhoele ho ngola likopo tse li sebelisang, likopo tse sa hatseleng ha li etsa ts'ebetso e telele. Ho sebelisa async / await ke sehlooho sa sengoloa se le seng kapa tse 'maloa, empa ke tla leka ho fumana lintlha tsa eona ka lipolelo tse' maloa:

  • async ke mofetoleli oa mokhoa oa ho khutlisa Mosebetsi kapa lefeela
  • mme e emetse ke opareitara e sa thibeleng Mosebetsi o emetseng.

Hape: motho ea emetseng, ka kakaretso (ho na le mekhelo), o tla lokolla khoele ea hona joale ea ts'ebetso ho ea pele, 'me ha Mosebetsi o qeta ts'ebetso ea oona, le khoele (ha e le hantle, ho ka ba ho nepahetseng ho bolela moelelo oa taba. , empa ho feta moo hamorao) e tla tsoelapele ho sebelisa mokhoa ona ho ea pele. Ka hare ho .NET, mochine ona o kenngoa ts'ebetsong ka mokhoa o ts'oanang le ts'ebetso ea lihlahisoa, ha mokhoa o ngotsoeng o fetoha sehlopha sohle, e leng mochine oa mmuso 'me o ka etsoa ka likotoana tse fapaneng ho itšetlehile ka linaha tsena. Mang kapa mang ea nang le thahasello a ka ngola khoutu efe kapa efe e bonolo a sebelisa asynс/await, bokella le ho sheba kopano a sebelisa JetBrains dotPeek e nang le Compiler Generated Code e lumelletsoeng.

Ha re shebeng likhetho tsa ho qala le ho sebelisa Task. Mohlala oa khoutu o ka tlase, re theha mosebetsi o mocha o sa sebetseng letho (Khoele.Boroko(10000)), empa bophelong ba sebele ona e lokela ho ba mosebetsi o boima oa CPU.

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
}

Mosebetsi o entsoe ka likhetho tse 'maloa:

  • LongRunning ke leseli la hore mosebetsi o ke ke oa phethoa kapele, ho bolelang hore ho ka ba molemo ho nahana ho se nke khoele ho tsoa letamong, empa ho theha e arohaneng bakeng sa Mosebetsi ona e le hore o se ke oa ntša ba bang kotsi.
  • AttachedToParent - Mesebetsi e ka hlophisoa ka sehlopha sa maemo. Haeba khetho ena e ne e sebelisoa, joale Mosebetsi o ka 'na oa e-ba boemong boo ka booona bo phethiloeng' me o emetse ho bolaoa ha bana ba oona.
  • PreferFairness - e bolela hore ho ka ba molemo ho phethahatsa Mesebetsi e rometsoeng pele ho tse rometsoeng hamorao. Empa sena ke khothaletso feela 'me liphetho ha lia tiisetsoa.

Paramethara ea bobeli e fetiselitsoeng ho mokhoa ke CancellationToken. Ho sebetsana ka nepo le ho hlakoloa ha ts'ebetso kamora hore e qale, khoutu e ntseng e etsoa e tlameha ho tlatsoa ka licheke bakeng sa boemo ba CancellationToken. Haeba ho se na licheke, joale mokhoa oa Hlakola o bitsoang ho CancellationTokenSource ntho e tla khona ho emisa ho etsoa ha Mosebetsi pele o qala.

Paramethara ea ho qetela ke ntho e hlophisitsoeng ea mofuta oa TaskScheduler. Sehlopha sena le litloholo tsa sona li etselitsoe ho laola maano a ho aba Mesebetsi ka likhoele;

Motho ea emetseng o sebelisoa ho Mosebetsi o bōpiloeng, e leng se bolelang hore khoutu e ngotsoeng ka mor'a eona, haeba e le teng, e tla etsoa ka moelelo o tšoanang (hangata sena se bolela khoele e le 'ngoe) le khoutu pele e emetse.

Mokhoa ona o tšoailoe e le async void, ho bolelang hore e ka sebelisa motho ea emetseng, empa khoutu ea mohala e ke ke ea khona ho emela ts'ebetso. Haeba tšobotsi e joalo e hlokahala, joale mokhoa o tlameha ho khutlisa Mosebetsi. Mekhoa e tšoailoeng ea async void e atile haholo: joalo ka molao, ke batho ba sebetsanang le liketsahalo kapa mekhoa e meng e sebetsang mollong le ho lebala molao-motheo. Haeba u hloka feela ho fana ka monyetla oa ho ema ho fihlela qetellong ea ho bolaoa, empa hape u khutlisetse sephetho, joale u lokela ho sebelisa Task.

Mosebetsing oo mokhoa oa StartNew o o khutlisitseng, hammoho le ho o mong le o mong, o ka letsetsa mokhoa oa ConfigureAwait ka parameter ea bohata, ebe ts'ebetso ka mor'a ho leta e ke ke ea tsoela pele eseng ka moelelo o hapuoeng, empa ka mokhoa o ikemetseng. Sena se lokela ho etsoa kamehla ha moelelo oa ts'ebetso e se oa bohlokoa bakeng sa khoutu ka mor'a ho leta. Hona hape ke khothaletso ho tsoa ho MS ha u ngola khoutu e tla romelloa ka har'a laeborari.

Ha re shebeng haholoanyane hore na u ka emela joang hore Mosebetsi o phethoe. Ka tlase ke mohlala oa khoutu, ka maikutlo a ha tebello e etsoa hantle ka maemo le ha e etsoa ka mokhoa o sa lokelang.

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
}

Mohlala oa pele, re emetse hore Mosebetsi o phethehe ntle le ho thibela khoele ea ho letsetsa; re tla khutlela ho sebetsa sephetho ha se se se le teng; ho fihlela ka nako eo, khoele ea ho letsetsa e tlohelloa lisebelisoa tsa eona.

Khethong ea bobeli, re thibela khoele ea ho letsetsa ho fihlela sephetho sa mokhoa se baloa. Sena se mpe eseng feela hobane re nkile khoele, sesebelisoa sa bohlokoa joalo sa lenaneo, ka botsoa bo bonolo, empa hape le hobane haeba khoutu ea mokhoa oo re o bitsang e na le emetse, 'me moelelo oa khokahano o hloka ho khutlela mohala oa mohala kamora emela, joale re tla fumana ho sa feleng : Khoele ea ho letsetsa e emetse hore sephetho sa mokhoa oa asynchronous se baloe, mokhoa oa asynchronous o leka ka lefeela ho tsoelapele ts'ebetsong ea eona khoeleng ea mohala.

Bothata bo bong ba mokhoa ona ke ho sebetsana le liphoso tse rarahaneng. 'Nete ke hore liphoso tsa khoutu ea asynchronous ha u sebelisa async / await li bonolo haholo ho sebetsana le tsona - li itšoara ka mokhoa o ts'oanang le haeba khoutu e lumellana. Leha re sebelisa synchronous wait exorcism ho Task, mokhelo oa mantlha o fetoha AggregateException, ke hore. Ho sebetsana le mokhelo, o tla tlameha ho hlahloba mofuta oa InnerException mme o ngole ketane ka har'a block e le 'ngoe kapa o sebelise ho tšoasa ha o haha, ho fapana le ketane ea li-blocks tse tsebahalang haholo lefatšeng la C #.

Mohlala oa boraro le oa ho qetela le ona o tšoailoe hampe ka lebaka le tšoanang 'me o na le mathata a tšoanang kaofela.

Mekhoa ea WhenAny le WhenAll e bonolo haholo bakeng sa ho emela sehlopha sa Mesebetsi; ba phuthela sehlopha sa Mesebetsi ho e 'ngoe, e tla thunya haeba Mosebetsi o tsoang sehlopheng o qala ho qala, kapa ha kaofela ba qetile ho e etsa.

Ho emisa likhoele

Ka mabaka a sa tšoaneng, ho ka 'na ha hlokahala ho emisa ho phalla ka mor'a hore e qale. Ho na le mekhoa e mengata ea ho etsa sena. Sehlopha sa Thread se na le mekhoa e 'meli e boletsoeng ka nepo: Ho ntša mpa и Ho sitisa. Ea pele ha e khothalletsoe haholo hore e sebelisoe, hobane ka mor'a ho e bitsa ka nako leha e le efe e sa reroang, nakong ea ts'ebetso ea taelo leha e le efe, ho tla etsoa mokhelo ThreadAbortedException. Ha u lebelle hore ho ka ba le mokhelo ha u eketsa palo e fapaneng, na ha ho joalo? 'Me ha u sebelisa mokhoa ona, sena ke boemo ba sebele haholo. Haeba o hloka ho thibela CLR ho hlahisa mokhelo o joalo karolong e itseng ea khoutu, o ka e phuthela ka mehala. Thread.BeginCriticalRegion, Thread.EndCriticalRegion. Khoutu efe kapa efe e ngotsoeng sebakeng sa ho qetela e phuthetsoe ka mehala e joalo. Ka lebaka lena, botebong ba khoutu ea moralo u ka fumana li-blocks ka teko e se nang letho, empa eseng e se nang letho qetellong. Microsoft e nyahamisa mokhoa ona hoo ba sa kang ba o kenyelletsa ho .net core.

Mokhoa oa Interrupt o sebetsa ka mokhoa o hlakileng haholoanyane. E ka sitisa khoele ntle le mokhelo ThreadInterruptedException feela nakong eo khoele e leng boemong ba ho leta. E kena sebakeng sena ha e ntse e leketlile WaitHandle, notlela, kapa ka mor'a ho letsetsa Thread.Sleep.

Likhetho tsena ka bobeli tse hlalositsoeng ka holimo li mpe ka lebaka la ho se tsejoe esale pele. Tharollo ke ho sebelisa sebopeho CancellationToken le sehlopha CancellationTokenSource. Taba ke ena: mohlala oa sehlopha sa CancellationTokenSource se thehiloe mme ke mong'a sona feela ea ka emisang ts'ebetso ka ho letsetsa mokhoa. Hlakola. Ke CancellationToken feela e fetisetsoang ts'ebetsong ka boeona. Beng ba CancellationToken ba ke ke ba hlakola ts'ebetso ka bobona, empa ba ka hlahloba feela hore na ts'ebetso e hlakotsoe. Ho na le thepa ea Boolean bakeng sa sena Ho Kopuoa le mokhoa ThrowIfCancelRequested. Ea ho qetela e tla lahla mokhelo TaskCancelledException haeba mokhoa oa Hlakola o ne o bitsoa ka mohlala oa CancellationToken o ntseng o etsoa parroted. 'Me ona ke mokhoa oo ke khothaletsang ho o sebelisa. Ena ke ntlafatso ho feta likhetho tse fetileng ka ho fumana taolo e felletseng mabapi le hore na ts'ebetso ea mokhelo e ka hlakoloa neng.

Khetho e sehlōhō ka ho fetisisa ea ho emisa khoele ke ho letsetsa Win32 API TerminateThread mosebetsi. Boitšoaro ba CLR ka mor'a ho letsetsa mosebetsi ona bo ka 'na ba se ke ba lebelloa. Ho MSDN ho ngotsoe tse latelang mabapi le ts'ebetso ena: "TerminateThread ke ts'ebetso e kotsi e lokelang ho sebelisoa feela maemong a feteletseng haholo. “

Ho fetolela API ea lefa ho ea ho Task Based ho sebelisa mokhoa oa FromAsync

Haeba u na le mahlohonolo a ho sebetsa morerong o qalileng ka mor'a hore Mesebetsi e hlahisoe 'me e khaotse ho baka tšabo e khutsitseng bakeng sa bahlahisi ba bangata, joale u ke ke ua tlameha ho sebetsana le li-API tse ngata tsa khale, tsa mekhatlo ea boraro le sehlopha sa hau. e hlokofalitse nakong e fetileng. Ka lehlohonolo, sehlopha sa .NET Framework se ile sa re hlokomela, le hoja mohlomong sepheo e ne e le ho itlhokomela. Leha ho ka ba joalo, .NET e na le lisebelisoa tse ngata tsa ho fetolela khoutu e se nang bohloko e ngotsoeng ka mekhoa ea khale ea asynchronous programming ho e ncha. E 'ngoe ea tsona ke mokhoa oa FromAsync oa TaskFactory. Mohlala oa khoutu o ka tlase, ke phuthela mekhoa ea khale ea async ea sehlopha sa WebRequest ka Mosebetsi ke sebelisa mokhoa ona.

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

Ona ke mohlala feela 'me ha ho na monyetla oa hore u etse sena ka mefuta e hahelletsoeng, empa morero ofe kapa ofe oa khale o tletse ka mekhoa ea BeginDoSomething e khutlisetsang mekhoa ea IAsyncResult le EndDoSomething e e amohelang.

Fetolela legacy API hore e be Task Based sebelisa sehlopha sa TaskCompletionSource

Sesebelisoa se seng sa bohlokoa se lokelang ho nahanoa ke sehlopha TaskCompletionSource. Mabapi le mesebetsi, morero le molao-motheo oa ts'ebetso, e ka 'na ea e-ba ntho e itseng e hopotsang mokhoa oa RegisterWaitForSingleObject oa sehlopha sa ThreadPool, seo ke se ngotseng ka holimo. U sebelisa sehlopha sena, u ka phuthela habonolo li-API tsa khale tsa asynchronous ho Tasks.

U tla re ke se ke buile ka mokhoa oa FromAsync oa sehlopha sa TaskFactory se reretsoeng merero ena. Mona re tla tlameha ho hopola histori eohle ea tsoelo-pele ea mehlala ea asynchronous ho .net eo Microsoft e faneng ka eona lilemong tse fetileng tsa 15: pele ho Task-Based Asynchronous Pattern (TAP), ho ne ho e-na le Asynchronous Programming Pattern (APP), eo e ne e bua ka mekhoa QALADoSomething returning IAsyncResult le mekhoa QETADoSomething e e amohelang le bakeng sa lefa la lilemo tsena mokhoa oa FromAsync o nepahetse, empa ha nako e ntse e ea, o ile oa nkeloa sebaka ke Event Based Asynchronous Pattern (LE AP), e neng e nka hore ketsahalo e tla phahamisoa ha ts'ebetso ea asynchronous e phethiloe.

TaskCompletionSource e nepahetse bakeng sa ho phuthela Tasks le li-API tsa lefa tse hahiloeng ho potoloha mofuta oa ketsahalo. Ntho ea bohlokoa ea mosebetsi oa eona ke e latelang: ntho ea sehlopha sena e na le thepa ea sechaba ea mofuta oa Task, boemo ba eona bo ka laoloang ka mekhoa ea SetResult, SetException, joalo-joalo ea sehlopha sa TaskCompletionSource. Libakeng tseo motho ea emetseng e kentsoeng tšebetsong ena, e tla etsoa kapa e hlolehe ntle le mokhelo ho latela mokhoa o sebelisitsoeng ho TaskCompletionSource. Haeba e ntse e sa hlaka, a re shebeng mohlala ona oa khoutu, moo EAP API ea khale e phuthetsoeng ka Mosebetsi o sebelisa TaskCompletionSource: ha ketsahalo e tuka, Mosebetsi o tla behoa boemong bo Phethiloeng, le mokhoa o sebelisitseng motho ea emetseng ho sebetsa. ho Mosebetsi ona o tla tsoelapele ts'ebetsong ea ona o amohetse ntho sephetho.

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

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

    result completionSource.Task;
}

Malebela le Maqheka a TaskCompletion

Ho phuthela li-API tsa khale ha se sohle se ka etsoang ho sebelisoa TaskCompletionSource. Ho sebelisa sehlopha sena ho bula monyetla o khahlisang oa ho rala li-API tse fapaneng ho Tasks tse sa nkeng likhoele. 'Me molapo, joalo ka ha re hopola, ke mohloli o theko e boima mme palo ea bona e lekanyelitsoe (haholo-holo ka palo ea RAM). Moeli ona o ka finyelloa habonolo ka ho ntshetsa pele, mohlala, ts'ebeliso ea marang-rang e laoloang ka mokhoa o rarahaneng oa khoebo. Ha re shebeng menyetla eo ke buang ka eona ha re kenya ts'ebetsong leqheka le kang la Nako e telele ea Polling.

Ka bokhutšoanyane, moelelo oa bolotsana ke ona: o hloka ho fumana boitsebiso bo tsoang ho API mabapi le liketsahalo tse ling tse hlahang ka lehlakoreng la eona, ha API, ka lebaka le itseng, e ke ke ea tlaleha ketsahalo eo, empa e ka khutlisetsa naha feela. Mohlala oa tsena ke li-API tsohle tse hahiloeng holim'a HTTP pele ho linako tsa WebSocket kapa ha ho ne ho sa khonehe ka lebaka le itseng ho sebelisa theknoloji ena. Moreki a ka botsa seva sa HTTP. Seva ea HTTP ha e khone ho qala puisano le moreki. Tharollo e bonolo ke ho khetha seva ho sebelisa nako, empa sena se baka mojaro o eketsehileng ho seva le ho lieha ho eketsehileng ka karolelano ea TimerInterval / 2. Ho pota-pota sena, ho ile ha qaptjoa leqheka le bitsoang Long Polling, le akarelletsang ho lieha ho arabela ho tloha. seva ho fihlela Timeout e fela kapa ketsahalo e tla etsahala. Haeba ketsahalo e etsahetse, joale e sebetsoa, ​​​​haeba ho se joalo, joale kopo e romelloa hape.

while(!eventOccures && !timeoutExceeded)  {

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

Empa tharollo e joalo e tla bonahala e le mpe hang ha palo ea bareki ba letetseng ketsahalo e eketseha, hobane ... Motho e mong le e mong ea joalo o lula a emetse ketsahalo. E, 'me re fumana ho lieha ho eketsehileng ha 1ms ha ketsahalo e tsosoa, hangata sena ha se bohlokoa, empa ke hobane'ng ha ho etsa hore software e mpe ho feta kamoo e ka bang kateng? Haeba re tlosa Thread.Sleep(1), joale ka lefeela re tla laela processor e le 'ngoe core 100% e sa sebetse, e potoloha ka potoloho e se nang thuso. U sebelisa TaskCompletionSource u ka etsa khoutu ena habonolo le ho rarolla mathata ohle a boletsoeng ka holimo:

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);
    }
}

Khoutu ena ha e so lokisetsoe tlhahiso, empa ke demo feela. Ho e sebelisa maemong a sebele, u boetse u hloka, bonyane, ho sebetsana le boemo ha molaetsa o fihla ka nako eo ho seng motho ea e lebeletseng: tabeng ena, mokhoa oa AsseptMessageAsync o lokela ho khutlisa Mosebetsi o seng o phethiloe. Haeba ena ke taba e atileng haholo, joale o ka nahana ka ho sebelisa ValueTask.

Ha re fumana kopo ea molaetsa, re theha le ho beha TaskCompletionSource ka har'a buka e hlalosang mantsoe, ebe re emela se etsahalang pele: nako e behiloeng e fela kapa molaetsa o amoheloa.

ValueTask: hobaneng le joang

Basebeletsi ba async / ba emetse, joalo ka mochine oa ho khutlisa lihlahisoa, ba hlahisa mochine oa mmuso ho tloha mokhoeng, 'me sena ke ho bōptjoa ha ntho e ncha, hoo e ka bang kamehla e seng ea bohlokoa, empa maemong a sa tloaelehang e ka baka bothata. Taba ena e kanna ea ba mokhoa o bitsoang hangata, re bua ka mehala ea mashome le likete tse makholo motsotsoana. Haeba mokhoa o joalo o ngotsoe ka tsela eo maemong a mangata o khutlisetsang sephetho ho feta mekhoa eohle e letetsoeng, joale .NET e fana ka sesebelisoa sa ho ntlafatsa sena - sebopeho sa ValueTask. Ho hlakisa, a re shebeng mohlala oa tšebeliso ea eona: ho na le cache eo re eang ho eona hangata. Ho na le litekanyetso ho eona ebe re li khutlisa feela; haeba ho se joalo, re ea ho IO e liehang ho ea li fumana. Ke batla ho etsa ea morao-rao ka mokhoa o ts'oanang, ho bolelang hore mokhoa oohle o fetoha o sa lumellaneng. Kahoo, mokhoa o hlakileng oa ho ngola mokhoa ke o latelang:

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

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

Ka lebaka la takatso ea ho ntlafatsa hanyane, le tšabo e nyane ea seo Roslyn a tla se hlahisa ha a hlophisa khoutu ena, o ka ngola mohlala ona hape ka tsela e latelang:

public Task<string> GetById(int id) {

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

Ka 'nete, tharollo e nepahetseng tabeng ena e tla ba ho ntlafatsa tsela e chesang, e leng, ho fumana boleng ho tswa ho dikishinari ntle le likabelo tse sa hlokahaleng le mojaro ho GC, ha maemong ao a sa tloaelehang re ntse re hloka ho ea ho IO bakeng sa data. , ntho e 'ngoe le e' ngoe e tla lula e le ho eketsa / ho tlosa tsela ea khale:

public ValueTask<string> GetById(int id) {

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

A re hlahlobisiseng karolo ena ea khoutu: haeba ho na le bohlokoa ka har'a cache, re theha mohaho, ho seng joalo mosebetsi oa sebele o tla phutheloa ka mokhoa o nang le moelelo. Khoutu ea mohala ha e tsotelle hore na khoutu ena e entsoe ka tsela efe: ValueTask, ho tsoa ponong ea C # syntax, e tla sebetsa joalo ka Mosebetsi o tloaelehileng ntlheng ena.

TaskSchedulers: ho laola maano a ho qala mosebetsi

API e latelang eo ke ratang ho e nahana ke sehlopha TaskScheduler le lihlahisoa tsa eona. Ke se ke boletse ka holimo hore TPL e na le bokhoni ba ho laola maano a ho aba Mesebetsi ho pholletsa le likhoele. Maano a joalo a hlalosoa ho litloholo tsa sehlopha sa TaskScheduler. Hoo e batlang e le leano leha e le lefe leo u ka le hlokang le ka fumanoa laebraring. ParallelExtensionsExtras, e entsoeng ke Microsoft, empa eseng karolo ea .NET, empa e fanoa e le sephutheloana sa Nuget. Ha re shebeng tse ling tsa tsona ka bokhutšoanyane:

  • CurrentThreadTaskScheduler - e etsa Mesebetsi ka khoele ea hona joale
  • LimitedConcurrencyLevelTaskScheduler - e fokotsa palo ea Mesebetsi e entsoeng ka nako e le 'ngoe ke parameter N, e amoheloang ho moetsi
  • OrderedTaskScheduler - e hlalosoa e le LimitedConcurrencyLevelTaskScheduler(1), kahoo mesebetsi e tla etsoa ka tatellano.
  • WorkStealingTaskScheduler - lisebelisoa ho utsoa mosebetsi mokhoa oa ho arola mesebetsi. Ha e le hantle ke ThreadPool e arohaneng. E rarolla bothata ba hore ho .NET ThreadPool ke sehlopha sa static, se le seng bakeng sa lits'ebetso tsohle, ho bolelang hore ho jara ha eona kapa tšebeliso e fosahetseng karolong e 'ngoe ea lenaneo ho ka lebisa litla-morao ho e' ngoe. Ho feta moo, ho thata haholo ho utloisisa sesosa sa mefokolo e joalo. Seo. Ho ka 'na ha hlokahala hore ho sebelisoe WorkStealingTaskSchedulers e arohaneng likarolong tsa lenaneo moo tšebeliso ea ThreadPool e ka bang mabifi le e sa lebelloang.
  • QueuedTaskScheduler - e o lumella ho etsa mesebetsi ho latela melao ea mela e tlang pele
  • ThreadPerTaskScheduler - e theha khoele e arohaneng bakeng sa Mosebetsi o mong le o mong o etsoang ho eona. E ka ba molemo bakeng sa mesebetsi e nkang nako e telele e sa lebelloang hore e phethoe.

Ho na le lintlha tse hlakileng sehlooho mabapi le TaskSchedulers ho microsoft blog.

Bakeng sa ho lokisa habonolo ntho e 'ngoe le e' ngoe e amanang le Mesebetsi, Visual Studio e na le fensetere ea Mesebetsi. Fesetereng ena u ka bona boemo ba hona joale ba mosebetsi, 'me u qhomele moleng o ntseng o etsoa oa khoutu.

.NET: Lisebelisoa tsa ho sebetsa ka multithreading le asynchrony. Karolo ea 1

PLinq le sehlopha sa Parallel

Ho phaella ho Mesebetsi le tsohle tse boletsoeng ka tsona, ho na le lisebelisoa tse ling tse peli tse thahasellisang ho .NET: PLinq (Linq2Parallel) le sehlopha sa Parallel. Ea pele e ts'episa ts'ebetso e ts'oanang ea ts'ebetso eohle ea Linq likhoeleng tse ngata. Palo ea likhoele e ka hlophisoa ho sebelisoa mokhoa oa katoloso oa WithDegreeOfParallelism. Ka bomalimabe, hangata PLinq ka mokhoa oa eona oa kamehla ha e na tlhahisoleseding e lekaneng mabapi le batho ba ka hare ho mohloli oa hau oa data ho fana ka phaello e kholo ea lebelo, ka lehlakoreng le leng, litšenyehelo tsa ho leka li tlaase haholo: o hloka feela ho letsetsa mokhoa oa AsParallel pele. letoto la mekhoa ea Linq le ho etsa liteko tsa ts'ebetso. Ho feta moo, hoa khoneha ho fetisetsa tlhahisoleseling e eketsehileng ho PLinq mabapi le mofuta oa mohloli oa data oa hau u sebelisa mochini oa Partitions. O ka bala ho feta mona и mona.

Sehlopha sa Parallel static se fana ka mekhoa ea ho pheta-pheta ka pokello ea Foreach ka ho ts'oana, ho phethahatsa Fore loop, le ho phethahatsa baemeli ba bangata ka ho tšoana Invoke. Phethahatso ea khoele ea hona joale e tla emisoa ho fihlela lipalo li phethiloe. Palo ea likhoele e ka hlophisoa ka ho fetisa ParallelOptions joalo ka khang ea ho qetela. U ka boela ua hlakisa TaskScheduler le CancellationToken u sebelisa likhetho.

fumanoeng ke

Ha ke qala ho ngola sehlooho sena ho latela thepa ea tlaleho ea ka le boitsebiso boo ke bo bokeletseng nakong ea mosebetsi oa ka ka mor'a eona, ke ne ke sa lebella hore ho tla ba le ho hongata hakana. Joale, ha mohlophisi oa mongolo moo ke ngolang sengoloa sena a mpolella ka nyeliso hore leqephe la 15 le felile, ke tla akaretsa liphetho tsa nakoana. Maqheka a mang, li-API, lisebelisoa tse bonahalang le maraba li tla tšohloa sehloohong se latelang.

Qeto:

  • U hloka ho tseba lisebelisoa tsa ho sebetsa ka likhoele, asynchrony le parallelism ho sebelisa lisebelisoa tsa li-PC tsa sejoale-joale.
  • NET e na le lisebelisoa tse ngata tse fapaneng bakeng sa merero ena
  • Hase kaofela ha tsona tse ileng tsa hlaha ka nako e le 'ngoe, kahoo hangata u ka fumana lefa, leha ho le joalo, ho na le litsela tsa ho fetola li-API tsa khale ntle le boiteko bo matla.
  • Ho sebetsa ka likhoele ho .NET e emeloa ke lihlopha tsa Thread le ThreadPool
  • Mekhoa ea Thread.Abort, Thread.Interrupt, le Win32 API TerminateThread e kotsi ebile ha e khothalletsoe hore e sebelisoe. Sebakeng seo, ho molemo ho sebelisa mochini oa CancellationToken
  • Phallo ke mohloli oa bohlokoa 'me phepelo ea eona e lekanyelitsoe. Maemo ao likhoele li tšoarehileng li emetse liketsahalo li lokela ho qojoa. Bakeng sa sena ho bonolo ho sebelisa sehlopha sa TaskCompletionSource
  • Lisebelisoa tse matla ka ho fetisisa le tse tsoetseng pele tsa .NET tsa ho sebetsa ka parallelism le asynchrony ke Mesebetsi.
  • Basebelisi ba c # async / await ba kenya tšebetsong mohopolo oa ho se thiba ho ema
  • O ka laola kabo ea Mesebetsi ho likhoele ka ho sebelisa litlelase tse nkiloeng ho TaskScheduler
  • Sebopeho sa ValueTask se ka thusa ho ntlafatsa litsela tse chesang le sephethephethe sa memori
  • Mesebetsi le likhoele tsa Visual Studio lifensetere li fana ka tlhaiso-leseling e ngata e bohlokoa bakeng sa ho lokisa likhoutu tse nang le likhoele tse ngata kapa tse sa lumellaneng.
  • PLinq ke sesebelisoa se pholileng, empa e kanna ea se be le tlhaiso-leseling e lekaneng mabapi le mohloli oa hau oa data, empa sena se ka lokisoa ka mokhoa oa ho arola.
  • E tla ntšetsoa pele…

Source: www.habr.com

Eketsa ka tlhaloso