.NET: Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚ΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с многопоточност ΠΈ асинхронност. Част 1

ΠŸΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π°ΠΌ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π°Ρ‚Π° статия Π½Π° Habr, Ρ‡ΠΈΠΉΡ‚ΠΎ ΠΏΡ€Π΅Π²ΠΎΠ΄ Π΅ ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π°Π½ Π² корпоративния публикация Π² Π±Π»ΠΎΠ³Π°.

НСобходимостта Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ Π½Π΅Ρ‰ΠΎ асинхронно, Π±Π΅Π· Π΄Π° сС Ρ‡Π°ΠΊΠ° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ Ρ‚ΡƒΠΊ ΠΈ сСга, ΠΈΠ»ΠΈ Π΄Π° сС Ρ€Π°Π·Π΄Π΅Π»ΠΈ голяма Ρ€Π°Π±ΠΎΡ‚Π° ΠΌΠ΅ΠΆΠ΄Ρƒ няколко Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ я ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚, ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°ΡˆΠ΅ ΠΏΡ€Π΅Π΄ΠΈ появата Π½Π° ΠΊΠΎΠΌΠΏΡŽΡ‚Ρ€ΠΈΡ‚Π΅. Π‘ появата ΠΈΠΌ Ρ‚Π°Π·ΠΈ Π½ΡƒΠΆΠ΄Π° стана ΠΌΠ½ΠΎΠ³ΠΎ осСзаСма. Π‘Π΅Π³Π°, ΠΏΡ€Π΅Π· 2019 Π³., пиша Ρ‚Π°Π·ΠΈ статия Π½Π° Π»Π°ΠΏΡ‚ΠΎΠΏ с 8-ядрСн процСсор Intel Core, Π½Π° ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ работят ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ сто процСси ΠΈ Π΄ΠΎΡ€ΠΈ ΠΏΠΎΠ²Π΅Ρ‡Π΅ нишки. Наблизо ΠΈΠΌΠ° Π»Π΅ΠΊΠΎ ΠΎΠΏΡŠΡ€ΠΏΠ°Π½ Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½, ΠΊΡƒΠΏΠ΅Π½ ΠΏΡ€Π΅Π΄ΠΈ няколко Π³ΠΎΠ΄ΠΈΠ½ΠΈ, ΠΈΠΌΠ° 8-ядрСн процСсор Π½Π° Π±ΠΎΡ€Π΄Π°. Π’Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΈΡ‚Π΅ рСсурси са пълни със статии ΠΈ Π²ΠΈΠ΄Π΅ΠΎΠΊΠ»ΠΈΠΏΠΎΠ²Π΅, Π² ΠΊΠΎΠΈΡ‚ΠΎ Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ ΠΈΠΌ сС Π²ΡŠΠ·Ρ…ΠΈΡ‰Π°Π²Π°Ρ‚ Π½Π° Ρ‚Π°Π·Π³ΠΎΠ΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ Π²ΠΎΠ΄Π΅Ρ‰ΠΈ смартфони с 16-ядрСни процСсори. MS Azure прСдоставя Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина със 20-ядрСн процСсор ΠΈ 128 TB RAM Π·Π° ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ ΠΎΡ‚ $2/час. Π—Π° съТалСниС Π΅ нСвъзмоТно Π΄Π° сС ΠΈΠ·Π²Π»Π΅Ρ‡Π΅ максимума ΠΈ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ρ‚Π°Π·ΠΈ сила, Π±Π΅Π· Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° управляватС взаимодСйствиСто Π½Π° Π½ΠΈΡˆΠΊΠΈΡ‚Π΅.

тСрминология

ΠŸΡ€ΠΎΡ†Π΅Ρ - OS ΠΎΠ±Π΅ΠΊΡ‚, ΠΈΠ·ΠΎΠ»ΠΈΡ€Π°Π½ΠΎ адрСсно пространство, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° нишки.
Нишка - OS ΠΎΠ±Π΅ΠΊΡ‚, Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠ°Ρ‚Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π·Π° изпълнСниС, част ΠΎΡ‚ процСс, Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ сподСлят ΠΏΠ°ΠΌΠ΅Ρ‚ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ рСсурси ΠΏΠΎΠΌΠ΅ΠΆΠ΄Ρƒ си Π² Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° процСс.
многозадачност - БобствСност Π½Π° ОБ, Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° стартиранС Π½Π° няколко процСса Π΅Π΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ
ΠœΠ½ΠΎΠ³ΠΎΡΠ΄Ρ€Π΅Π½ - свойство Π½Π° процСсора, способността Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ няколко ядра Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° Π΄Π°Π½Π½ΠΈ
ΠœΡƒΠ»Ρ‚ΠΈΠΏΡ€ΠΎΡ†Π΅ΡΠΎΡ€Π½ΠΎΡΡ‚ - свойство Π½Π° ΠΊΠΎΠΌΠΏΡŽΡ‚ΡŠΡ€, способността Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈ Π΅Π΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ с няколко процСсора физичСски
ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ β€” свойство Π½Π° процСс, способността Π΄Π° сС разпрСдСля ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° Π΄Π°Π½Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ няколко нишки.
ΠŸΠ°Ρ€Π°Π»Π΅Π»ΠΈΠ·ΡŠΠΌ - ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Π½Π΅ Π½Π° няколко дСйствия физичСски Π΅Π΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π·Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π²Ρ€Π΅ΠΌΠ΅
Асинхронност β€” изпълнСниС Π½Π° опСрация Π±Π΅Π· ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚Π°Π·ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°; Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ ΠΎΡ‚ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΏΠΎ-късно.

ΠΌΠ΅Ρ‚Π°Ρ„ΠΎΡ€Π°

НС всички опрСдСлСния са Π΄ΠΎΠ±Ρ€ΠΈ ΠΈ някои сС нуТдаят ΠΎΡ‚ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ обяснСниС, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Ρ‰Π΅ добавя ΠΌΠ΅Ρ‚Π°Ρ„ΠΎΡ€Π° Π·Π° Π³ΠΎΡ‚Π²Π΅Π½Π΅Ρ‚ΠΎ Π½Π° закуска към ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»Π½ΠΎ Π²ΡŠΠ²Π΅Π΄Π΅Π½Π°Ρ‚Π° тСрминология. Π“ΠΎΡ‚Π²Π΅Π½Π΅Ρ‚ΠΎ Π½Π° закуска Π² Ρ‚Π°Π·ΠΈ ΠΌΠ΅Ρ‚Π°Ρ„ΠΎΡ€Π° Π΅ процСс.

Π”ΠΎΠΊΠ°Ρ‚ΠΎ приготвях закуската сутрин (процСсор) ΠΈΠ΄Π²Π°ΠΌ Π² кухнята (ΠΊΠΎΠΌΠΏΡŽΡ‚ΡŠΡ€). ΠΈΠΌΠ°ΠΌ 2 Ρ€ΡŠΡ†Π΅ (Π¦Π²Π΅Ρ‚ΠΎΠ²Π΅). Π’ кухнята ΠΈΠΌΠ° Ρ€Π΅Π΄ΠΈΡ†Π° устройства (IO): Ρ„ΡƒΡ€Π½Π°, Ρ‡Π°ΠΉΠ½ΠΈΠΊ, тостСр, Ρ…Π»Π°Π΄ΠΈΠ»Π½ΠΈΠΊ. ΠŸΡƒΡΠΊΠ°ΠΌ Π³Π°Π·Ρ‚Π°, слагам Ρ‚ΠΈΠ³Π°Π½ ΠΈ Π½Π°Π»ΠΈΠ²Π°ΠΌ ΠΎΠ»ΠΈΠΎ, Π±Π΅Π· Π΄Π° Ρ‡Π°ΠΊΠ°ΠΌ Π΄Π° Π·Π°Π³Ρ€Π΅Π΅ (асинхронно, Non-Blocking-IO-Wait), вадя яйцата ΠΎΡ‚ Ρ…Π»Π°Π΄ΠΈΠ»Π½ΠΈΠΊΠ° ΠΈ Π³ΠΈ счупвам Π² чиния, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ Π³ΠΈ Ρ€Π°Π·Π±ΠΈΠ²Π°ΠΌ с Π΅Π΄Π½Π° Ρ€ΡŠΠΊΠ° (Π’Π΅ΠΌΠ° β„–1), ΠΈ Π²Ρ‚ΠΎΡ€ΠΎ (Π’Π΅ΠΌΠ° β„–2), Π΄ΡŠΡ€ΠΆΠ°Ρ‰ Ρ‚Π°Π±Π΅Π»Π°Ρ‚Π° (Π‘ΠΏΠΎΠ΄Π΅Π»Π΅Π½ рСсурс). Π‘Π΅Π³Π° Π±ΠΈΡ… искал Π΄Π° Π²ΠΊΠ»ΡŽΡ‡Π° Ρ‡Π°ΠΉΠ½ΠΈΠΊΠ°, Π½ΠΎ нямам Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ Ρ€ΡŠΡ†Π΅ (Π“Π»Π°Π΄ Π½Π° Ρ‚Π΅ΠΌΠ°Ρ‚Π°) ΠŸΡ€Π΅Π· Ρ‚ΠΎΠ²Π° Π²Ρ€Π΅ΠΌΠ΅ загрява Ρ‚ΠΈΠ³Π°Π½Π° (ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π°ΠΌ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π°) Π² ΠΊΠΎΠΉΡ‚ΠΎ изсипвам Ρ€Π°Π·Π±ΠΈΡ‚ΠΎΡ‚ΠΎ. Посягам към Ρ‡Π°ΠΉΠ½ΠΈΠΊΠ°, Π²ΠΊΠ»ΡŽΡ‡Π²Π°ΠΌ Π³ΠΎ ΠΈ Π³Π»ΡƒΠΏΠ°Π²ΠΎ Π³Π»Π΅Π΄Π°ΠΌ ΠΊΠ°ΠΊ Π²ΠΎΠ΄Π°Ρ‚Π° ΠΊΠΈΠΏΠΈ Π² Π½Π΅Π³ΠΎ (Π‘Π»ΠΎΠΊΠΈΡ€Π°Π½Π΅-IO-Π˜Π·Ρ‡Π°ΠΊΠ°ΠΉΡ‚Π΅), Π²ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‡Π΅ ΠΏΡ€Π΅Π· Ρ‚ΠΎΠ²Π° Π²Ρ€Π΅ΠΌΠ΅ моТСшС Π΄Π° ΠΈΠ·ΠΌΠΈΠ΅ чинията, Π² която Ρ€Π°Π·Π±ΠΈ ΠΎΠΌΠ»Π΅Ρ‚Π°.

Π‘Π³ΠΎΡ‚Π²ΠΈΡ… ΠΎΠΌΠ»Π΅Ρ‚ само с 2 Ρ€ΡŠΡ†Π΅ ΠΈ нямам ΠΏΠΎΠ²Π΅Ρ‡Π΅, Π½ΠΎ Π² ΡΡŠΡ‰ΠΎΡ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π½Π° Ρ€Π°Π·Π±ΠΈΠ²Π°Π½Π΅ Π½Π° ΠΎΠΌΠ»Π΅Ρ‚Π° сС случиха 3 ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ навСднъТ: Ρ€Π°Π·Π±ΠΈΠ²Π°Π½Π΅ Π½Π° ΠΎΠΌΠ»Π΅Ρ‚Π°, Π·Π°Π΄ΡŠΡ€ΠΆΠ°Π½Π΅ Π½Π° чинията, нагряванС Π½Π° Ρ‚ΠΈΠ³Π°Π½Π° , ΠŸΡ€ΠΎΡ†Π΅ΡΠΎΡ€ΡŠΡ‚ Π΅ Π½Π°ΠΉ-Π±ΡŠΡ€Π·Π°Ρ‚Π° част ΠΎΡ‚ ΠΊΠΎΠΌΠΏΡŽΡ‚ΡŠΡ€Π°, IO Π΅ Ρ‚ΠΎΠ²Π°, ΠΊΠΎΠ΅Ρ‚ΠΎ Π½Π°ΠΉ-чСсто сС забавя, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ чСсто Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π΅ Π΄Π° Π·Π°Π΅ΠΌΠ΅Ρ‚Π΅ процСсора с Π½Π΅Ρ‰ΠΎ, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ‚Π΅ Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ IO.

ΠŸΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π°ΠΉΠΊΠΈ ΠΌΠ΅Ρ‚Π°Ρ„ΠΎΡ€Π°Ρ‚Π°:

  • Ако Π² процСса Π½Π° приготвянС Π½Π° ΠΎΠΌΠ»Π΅Ρ‚ Π±ΠΈΡ… сС ΠΎΠΏΠΈΡ‚Π°Π» Π΄Π° сС ΠΏΡ€Π΅ΠΎΠ±Π»Π΅ΠΊΠ°, Ρ‚ΠΎΠ²Π° Π±ΠΈ Π±ΠΈΠ»ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° многозадачност. Π’Π°ΠΆΠ΅Π½ нюанс: ΠΊΠΎΠΌΠΏΡŽΡ‚Ρ€ΠΈΡ‚Π΅ са ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€ΠΈ Π² Ρ‚ΠΎΠ²Π° ΠΎΡ‚ Ρ…ΠΎΡ€Π°Ρ‚Π°.
  • ΠšΡƒΡ…Π½Ρ с няколко Π³ΠΎΡ‚Π²Π°Ρ‡ΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² рСсторант - многоядрСн ΠΊΠΎΠΌΠΏΡŽΡ‚ΡŠΡ€.
  • Много рСсторанти Π² Π·Π°Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π·Π° Ρ…Ρ€Π°Π½Π΅Π½Π΅ Π² Ρ‚ΡŠΡ€Π³ΠΎΠ²ΡΠΊΠΈ Ρ†Π΅Π½Ρ‚ΡŠΡ€ - Ρ†Π΅Π½Ρ‚ΡŠΡ€ Π·Π° Π΄Π°Π½Π½ΠΈ

.NET инструмСнти

.NET Π΅ Π΄ΠΎΠ±ΡŠΡ€ Π² Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° с нишки, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ с ΠΌΠ½ΠΎΠ³ΠΎ Π΄Ρ€ΡƒΠ³ΠΈ Π½Π΅Ρ‰Π°. Π‘ всяка Π½ΠΎΠ²Π° вСрсия Ρ‚ΠΎΠΉ въвСТда всС ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΈ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π½ΠΎΠ²ΠΈ инструмСнти Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с тях, Π½ΠΎΠ²ΠΈ слоСвС Π½Π° абстракция Π²ΡŠΡ€Ρ…Ρƒ OS нишки. ΠšΠΎΠ³Π°Ρ‚ΠΎ работят с ΠΈΠ·Π³Ρ€Π°ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° абстракции, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈΡ‚Π΅ Π½Π° Ρ€Π°ΠΌΠΊΠ° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ оставя Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚Ρ‚Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° абстракция ΠΎΡ‚ високо Π½ΠΈΠ²ΠΎ, Π΄Π° сС спуснС Π΅Π΄Π½ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π½ΠΈΠ²Π° ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ. Най-чСсто Ρ‚ΠΎΠ²Π° Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ отваря Π²Ρ€Π°Ρ‚Π°Ρ‚Π° Π΄Π° сС прострСлятС Π² ΠΊΡ€Π°ΠΊΠ° с ΠΏΡƒΡˆΠΊΠ°, Π½ΠΎ понякога, Π² Ρ€Π΅Π΄ΠΊΠΈ случаи, ΠΌΠΎΠΆΠ΅ Π΄Π° Π΅ СдинствСният Π½Π°Ρ‡ΠΈΠ½ Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, ΠΊΠΎΠΉΡ‚ΠΎ Π½Π΅ Π΅ Ρ€Π΅ΡˆΠ΅Π½ Π½Π° ΡΠ΅Π³Π°ΡˆΠ½ΠΎΡ‚ΠΎ Π½ΠΈΠ²ΠΎ Π½Π° абстракция .

Под инструмСнти ΠΈΠΌΠ°ΠΌ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ ΠΊΠ°ΠΊΡ‚ΠΎ интСрфСйси Π·Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅ Π½Π° прилоТСния (API), прСдоставСни ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° Ρ‚Ρ€Π΅Ρ‚ΠΈ страни, Ρ‚Π°ΠΊΠ° ΠΈ Ρ†Π΅Π»ΠΈ софтуСрни Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ, ΠΊΠΎΠΈΡ‚ΠΎ опростяват Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅Ρ‚ΠΎ Π½Π° всякакви ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ с многонишков ΠΊΠΎΠ΄.

Π‘Ρ‚Π°Ρ€Ρ‚ΠΈΡ€Π°Π½Π΅ Π½Π° нишка

ΠšΠ»Π°ΡΡŠΡ‚ Thread Π΅ Π½Π°ΠΉ-основният клас Π² .NET Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с нишки. ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ΡŠΡ‚ ΠΏΡ€ΠΈΠ΅ΠΌΠ° Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π΄Π²Π° Π΄Π΅Π»Π΅Π³Π°Ρ‚Π°:

  • ThreadStart β€” Няма ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ
  • ParametrizedThreadStart - с Π΅Π΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ ΠΎΡ‚ Ρ‚ΠΈΠΏ ΠΎΠ±Π΅ΠΊΡ‚.

Π”Π΅Π»Π΅Π³Π°Ρ‚ΡŠΡ‚ Ρ‰Π΅ бъдС изпълнСн Π² Π½ΠΎΠ²ΠΎΡΡŠΠ·Π΄Π°Π΄Π΅Π½Π°Ρ‚Π° нишка слСд ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Start.Ако към конструктора Π΅ ΠΏΡ€Π΅Π΄Π°Π΄Π΅Π½ Π΄Π΅Π»Π΅Π³Π°Ρ‚ ΠΎΡ‚ Ρ‚ΠΈΠΏ ParametrizedThreadStart, Ρ‚ΠΎΠ³Π°Π²Π° към ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Start трябва Π΄Π° бъдС ΠΏΡ€Π΅Π΄Π°Π΄Π΅Π½ ΠΎΠ±Π΅ΠΊΡ‚. Π’ΠΎΠ·ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π·Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° всяка Π»ΠΎΠΊΠ°Π»Π½Π° информация към ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π‘Ρ‚Ρ€ΡƒΠ²Π° си Π΄Π° сС ΠΎΡ‚Π±Π΅Π»Π΅ΠΆΠΈ, Ρ‡Π΅ ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° нишка Π΅ скъпа опСрация, Π° самата нишка Π΅ Ρ‚Π΅ΠΆΡŠΠΊ ΠΎΠ±Π΅ΠΊΡ‚, Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΎΡ‚ΠΎ Π·Π°Ρ‰ΠΎΡ‚ΠΎ разпрСдСля 1MB ΠΏΠ°ΠΌΠ΅Ρ‚ Π² стСка ΠΈ изисква взаимодСйствиС с OS API.

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

ΠšΠ»Π°ΡΡŠΡ‚ ThreadPool прСдставлява концСпцията Π·Π° ΠΏΡƒΠ». Π’ .NET ΠΏΡƒΠ»ΡŠΡ‚ ΠΎΡ‚ нишки Π΅ част ΠΎΡ‚ инТСнСрството ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈΡ‚Π΅ ΠΎΡ‚ Microsoft са ΠΏΠΎΠ»ΠΎΠΆΠΈΠ»ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ усилия, Π·Π° Π΄Π° сС увСрят, Ρ‡Π΅ Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΎ Π² голямо Ρ€Π°Π·Π½ΠΎΠΎΠ±Ρ€Π°Π·ΠΈΠ΅ ΠΎΡ‚ сцСнарии.

ΠžΠ±Ρ‰Π° концСпция:

ΠžΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, Π² ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ стартира, Ρ‚ΠΎ създава няколко нишки Π² Ρ€Π΅Π·Π΅Ρ€Π² във Ρ„ΠΎΠ½ΠΎΠ² Ρ€Π΅ΠΆΠΈΠΌ ΠΈ прСдоставя Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚Ρ‚Π° Π΄Π° Π³ΠΈ Π²Π·Π΅ΠΌΠ΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅. Ако Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ чСсто ΠΈ Π² голям Π±Ρ€ΠΎΠΉ, ΠΏΡƒΠ»ΡŠΡ‚ сС Ρ€Π°Π·ΡˆΠΈΡ€ΡΠ²Π°, Π·Π° Π΄Π° ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ΠΈ Π½Π° Π½ΡƒΠΆΠ΄ΠΈΡ‚Π΅ Π½Π° повикващия. ΠšΠΎΠ³Π°Ρ‚ΠΎ Π² ΠΏΡƒΠ»Π° няма свободни нишки Π² подходящия ΠΌΠΎΠΌΠ΅Π½Ρ‚, Ρ‚ΠΎΠΉ ΠΈΠ»ΠΈ Ρ‰Π΅ ΠΈΠ·Ρ‡Π°ΠΊΠ° Π΅Π΄Π½Π° ΠΎΡ‚ Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ Π΄Π° сС Π²ΡŠΡ€Π½Π΅, ΠΈΠ»ΠΈ Ρ‰Π΅ създадС Π½ΠΎΠ²Π°. ΠžΡ‚ Ρ‚ΠΎΠ²Π° слСдва, Ρ‡Π΅ ΠΏΡƒΠ»ΡŠΡ‚ ΠΎΡ‚ нишки Π΅ чудСсСн Π·Π° някои краткосрочни дСйствия ΠΈ Π½Π΅ Π΅ подходящ Π·Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ ΠΊΠ°Ρ‚ΠΎ услуги ΠΏΡ€Π΅Π· цялата Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ.

Π—Π° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ нишка ΠΎΡ‚ ΠΏΡƒΠ»Π°, ΠΈΠΌΠ° ΠΌΠ΅Ρ‚ΠΎΠ΄ QueueUserWorkItem, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡ€ΠΈΠ΅ΠΌΠ° Π΄Π΅Π»Π΅Π³Π°Ρ‚ ΠΎΡ‚ Ρ‚ΠΈΠΏ WaitCallback, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠΌΠ° ΡΡŠΡ‰ΠΈΡ подпис ΠΊΠ°Ρ‚ΠΎ ParametrizedThreadStart ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ΡŠΡ‚, ΠΏΠΎΠ΄Π°Π΄Π΅Π½ към Π½Π΅Π³ΠΎ, изпълнява ΡΡŠΡ‰Π°Ρ‚Π° функция.

ThreadPool.QueueUserWorkItem(...);

По-ΠΌΠ°Π»ΠΊΠΎ извСстният ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π° ΠΏΡƒΠ»Π° ΠΎΡ‚ нишки RegisterWaitForSingleObject сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€Π°Ρ‰ΠΈ IO ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π”Π΅Π»Π΅Π³Π°Ρ‚ΡŠΡ‚, ΠΏΡ€Π΅Π΄Π°Π²Π°Π½ Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄, Ρ‰Π΅ бъдС ΠΈΠ·Π²ΠΈΠΊΠ°Π½, ΠΊΠΎΠ³Π°Ρ‚ΠΎ WaitHandle, ΠΏΡ€Π΅Π΄Π°Π²Π°Π½ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, Π΅ β€žΠžΡΠ²ΠΎΠ±ΠΎΠ΄Π΅Π½β€œ.

ThreadPool.RegisterWaitForSingleObject(...)

.NET ΠΈΠΌΠ° Ρ‚Π°ΠΉΠΌΠ΅Ρ€ Π·Π° нишки ΠΈ сС Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π° ΠΎΡ‚ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π½Π° WinForms/WPF ΠΏΠΎ Ρ‚ΠΎΠ²Π°, Ρ‡Π΅ нСговият ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ Ρ‰Π΅ бъдС ΠΈΠ·Π²ΠΈΠΊΠ°Π½ Π½Π° нишка, Π²Π·Π΅Ρ‚Π° ΠΎΡ‚ ΠΏΡƒΠ»Π°.

System.Threading.Timer

Има ΠΈ доста Π΅ΠΊΠ·ΠΎΡ‚ΠΈΡ‡Π΅Π½ Π½Π°Ρ‡ΠΈΠ½ Π·Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° Π΄Π΅Π»Π΅Π³Π°Ρ‚ Π·Π° изпълнСниС към нишка ΠΎΡ‚ ΠΏΡƒΠ»Π° - ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ BeginInvoke.

DelegateInstance.BeginInvoke

Π‘ΠΈΡ… искал Π½Π°ΠΊΡ€Π°Ρ‚ΠΊΠΎ Π΄Π° сС спра Π½Π° функцията, към която ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΈΠ·Π²ΠΈΠΊΠ°Π½ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΡ‚ Π³ΠΎΡ€Π½ΠΈΡ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ - CreateThread ΠΎΡ‚ Kernel32.dll Win32 API. Има Π½Π°Ρ‡ΠΈΠ½, Π±Π»Π°Π³ΠΎΠ΄Π°Ρ€Π΅Π½ΠΈΠ΅ Π½Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° Π½Π° Π²ΡŠΠ½ΡˆΠ½ΠΈΡ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ, Π΄Π° ΠΈΠ·Π²ΠΈΠΊΠ°Ρ‚Π΅ Ρ‚Π°Π·ΠΈ функция. Π’ΠΈΠΆΠ΄Π°Π» съм Ρ‚Π°ΠΊΠΎΠ²Π° ΠΎΠ±Π°ΠΆΠ΄Π°Π½Π΅ само вСднъТ Π² уТасСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° наслСдСн ΠΊΠΎΠ΄ ΠΈ мотивацията Π½Π° Π°Π²Ρ‚ΠΎΡ€Π°, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ Π½Π°ΠΏΡ€Π°Π²ΠΈΠ» Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚ΠΎΠ²Π°, всС ΠΎΡ‰Π΅ остава Π·Π°Π³Π°Π΄ΠΊΠ° Π·Π° ΠΌΠ΅Π½.

Kernel32.dll CreateThread

ΠŸΡ€Π΅Π³Π»Π΅Π΄ ΠΈ отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ Π² нишки

ΠΠΈΡˆΠΊΠΈΡ‚Π΅, създадСни ΠΎΡ‚ вас, всички ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ Π½Π° Ρ‚Ρ€Π΅Ρ‚ΠΈ страни ΠΈ ΠΏΡƒΠ»ΡŠΡ‚ .NET ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС видят Π² ΠΏΡ€ΠΎΠ·ΠΎΡ€Π΅Ρ†Π° Threads Π½Π° Visual Studio. Π’ΠΎΠ·ΠΈ ΠΏΡ€ΠΎΠ·ΠΎΡ€Π΅Ρ† Ρ‰Π΅ ΠΏΠΎΠΊΠ°Π·Π²Π° информация Π·Π° Π½ΠΈΡˆΠΊΠ°Ρ‚Π° само ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΅ Π² процСс Π½Π° отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ ΠΈ Π² Ρ€Π΅ΠΆΠΈΠΌ Π½Π° ΠΏΡ€Π΅ΠΊΡŠΡΠ²Π°Π½Π΅. Π’ΡƒΠΊ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΈΠΌΠ΅Π½Π°Ρ‚Π° Π½Π° стСка ΠΈ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΈΡ‚Π΅ Π½Π° всяка нишка ΠΈ Π΄Π° ΠΏΡ€Π΅Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ отстраняванСто Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ към ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Π° нишка. Използвайки свойството Priority Π½Π° класа Thread, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π·Π°Π΄Π°Π΄Π΅Ρ‚Π΅ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° Π½Π° Π½ΠΈΡˆΠΊΠ°Ρ‚Π°, ΠΊΠΎΠΉΡ‚ΠΎ OC ΠΈ CLR Ρ‰Π΅ Π²ΡŠΠ·ΠΏΡ€ΠΈΠ΅ΠΌΠ°Ρ‚ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΠΊΠ° ΠΏΡ€ΠΈ раздСлянСто Π½Π° процСсорното Π²Ρ€Π΅ΠΌΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΡˆΠΊΠΈΡ‚Π΅.

.NET: Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚ΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с многопоточност ΠΈ асинхронност. Част 1

ΠŸΠ°Ρ€Π°Π»Π΅Π»Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅

Task Parallel Library (TPL) бСшС въвСдСна Π² .NET 4.0. Π‘Π΅Π³Π° Ρ‚ΠΎΠ²Π° Π΅ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚ΡŠΡ‚ ΠΈ основният инструмСнт Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с асинхронност. ВсСки ΠΊΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΏΠΎ-стар ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, сС счита Π·Π° наслСдСн. ΠžΡΠ½ΠΎΠ²Π½Π°Ρ‚Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Π° Π½Π° TPL Π΅ ΠΊΠ»Π°ΡΡŠΡ‚ Task ΠΎΡ‚ пространството Π½Π° ΠΈΠΌΠ΅Π½Π°Ρ‚Π° System.Threading.Tasks. Π—Π°Π΄Π°Ρ‡Π°Ρ‚Π° Π΅ абстракция Π½Π°Π΄ нишка. Π‘ Π½ΠΎΠ²Π°Ρ‚Π° вСрсия Π½Π° Π΅Π·ΠΈΠΊΠ° C# ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ Π΅Π»Π΅Π³Π°Π½Ρ‚Π΅Π½ Π½Π°Ρ‡ΠΈΠ½ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° със Tasks - async/await ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΈ. Π’Π΅Π·ΠΈ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ…Π° възмоТно писанСто Π½Π° асинхронСн ΠΊΠΎΠ΄, сякаш бСшС прост ΠΈ синхронСн, ΠΊΠΎΠ΅Ρ‚ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈ възмоТно Π΄ΠΎΡ€ΠΈ Π·Π° Ρ…ΠΎΡ€Π° с ΠΌΠ°Π»ΠΊΠΎ Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ Π½Π° Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ Π΄Π° ΠΏΠΈΡˆΠ°Ρ‚ прилоТСния, ΠΊΠΎΠΈΡ‚ΠΎ Π³ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚, прилоТСния, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ Π·Π°ΠΌΡ€ΡŠΠ·Π²Π°Ρ‚ ΠΏΡ€ΠΈ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Π½Π΅ Π½Π° дълги ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π˜Π·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° async/await Π΅ Ρ‚Π΅ΠΌΠ° Π·Π° Π΅Π΄Π½Π° ΠΈΠ»ΠΈ Π΄ΠΎΡ€ΠΈ няколко статии, Π½ΠΎ Ρ‰Π΅ сС ΠΎΠΏΠΈΡ‚Π°ΠΌ Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π° ΡΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° ΠΉ Π² няколко изрСчСния:

  • async Π΅ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄, Π²Ρ€ΡŠΡ‰Π°Ρ‰ Task ΠΈΠ»ΠΈ void
  • Π° await Π΅ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€Π°Ρ‰ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π·Π° Ρ‡Π°ΠΊΠ°Ρ‰Π° Π·Π°Π΄Π°Ρ‡Π°.

ΠžΡ‰Π΅ вСднъТ: ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΡŠΡ‚ await, Π² общия случай (ΠΈΠΌΠ° ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ), Ρ‰Π΅ освободи Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° нишка Π½Π° изпълнСниС ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΠΊ ΠΈ ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π—Π°Π΄Π°Ρ‡Π°Ρ‚Π° ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡ΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ си, ΠΈ Π½ΠΈΡˆΠΊΠ°Ρ‚Π° (Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚ Π±ΠΈ Π±ΠΈΠ»ΠΎ ΠΏΠΎ-ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ Π΄Π° сС ΠΊΠ°ΠΆΠ΅ ΠΊΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ΡŠΡ‚ , Π½ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π·Π° Ρ‚ΠΎΠ²Π° ΠΏΠΎ-късно) Ρ‰Π΅ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈ Π΄Π° изпълнява ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΠΊ. Π’ΡŠΡ‚Ρ€Π΅ Π² .NET Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ сС ΠΏΡ€ΠΈΠ»Π°Π³Π° ΠΏΠΎ ΡΡŠΡ‰ΠΈΡ Π½Π°Ρ‡ΠΈΠ½ ΠΊΠ°Ρ‚ΠΎ Π²Ρ€ΡŠΡ‰Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π΄ΠΎΠ±ΠΈΠ²Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ написаният ΠΌΠ΅Ρ‚ΠΎΠ΄ сС ΠΏΡ€Π΅Π²Ρ€ΡŠΡ‰Π° Π² цял клас, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ машина Π·Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΡ ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС изпълнява Π½Π° ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ части Π² зависимост ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΡ. ВсСки, ΠΊΠΎΠΉΡ‚ΠΎ сС интСрСсува, ΠΌΠΎΠΆΠ΅ Π΄Π° напишС всСки прост ΠΊΠΎΠ΄ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° asynс/await, Π΄Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π° ΠΈ ΠΏΡ€Π΅Π³Π»Π΅Π΄Π° асСмблиранСто с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° JetBrains dotPeek с Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°Π½ ΠΊΠΎΠ΄, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½ ΠΎΡ‚ ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€.

НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΎΠΏΡ†ΠΈΠΈΡ‚Π΅ Π·Π° стартиранС ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Task. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° с ΠΊΠΎΠ΄ ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ създавамС Π½ΠΎΠ²Π° Π·Π°Π΄Π°Ρ‡Π°, която Π½Π΅ ΠΏΡ€Π°Π²ΠΈ Π½ΠΈΡ‰ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ (Thread.Sleep(10000)), Π½ΠΎ Π² рСалния ΠΆΠΈΠ²ΠΎΡ‚ Ρ‚ΠΎΠ²Π° Π±ΠΈ трябвало Π΄Π° Π΅ слоТна 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
}

Бъздава сС Π·Π°Π΄Π°Ρ‡Π° с няколко ΠΎΠΏΡ†ΠΈΠΈ:

  • LongRunning Π΅ Π½Π°ΠΌΠ΅ΠΊ, Ρ‡Π΅ Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π° няма Π΄Π° бъдС изпълнСна Π±ΡŠΡ€Π·ΠΎ, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° си струва Π΄Π° обмислитС Π΄Π° Π½Π΅ Π²Π·Π΅ΠΌΠ΅Ρ‚Π΅ нишка ΠΎΡ‚ ΠΏΡƒΠ»Π°, Π° Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ ΠΎΡ‚Π΄Π΅Π»Π½Π° Π·Π° Ρ‚Π°Π·ΠΈ Π·Π°Π΄Π°Ρ‡Π°, Π·Π° Π΄Π° Π½Π΅ Π½Π°Π²Ρ€Π΅Π΄ΠΈΡ‚Π΅ Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅.
  • AttachedToParent - Π—Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΏΠΎΠ΄Ρ€Π΅Π΄Π΅Π½ΠΈ Π² йСрархия. Ако Ρ‚Π°Π·ΠΈ опция Π΅ Π±ΠΈΠ»Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π°, Ρ‚ΠΎΠ³Π°Π²Π° Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π΅ Π² ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅, Π² ΠΊΠΎΠ΅Ρ‚ΠΎ самата тя Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠΈΠ»Π° ΠΈ Ρ‡Π°ΠΊΠ° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° своитС Π΄Π΅Ρ†Π°.
  • PreferFairness - ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ Π±ΠΈ Π±ΠΈΠ»ΠΎ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΡ‚ Π—Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅, ΠΈΠ·ΠΏΡ€Π°Ρ‚Π΅Π½ΠΈ Π·Π° изпълнСниС ΠΏΠΎ-Ρ€Π°Π½ΠΎ, ΠΏΡ€Π΅Π΄ΠΈ Ρ‚Π΅Π·ΠΈ, ΠΈΠ·ΠΏΡ€Π°Ρ‚Π΅Π½ΠΈ ΠΏΠΎ-късно. Но Ρ‚ΠΎΠ²Π° Π΅ само ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΠΊΠ° ΠΈ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈΡ‚Π΅ Π½Π΅ са Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π°Π½ΠΈ.

Вторият ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€, ΠΏΡ€Π΅Π΄Π°Π΄Π΅Π½ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, Π΅ CancellationToken. Π—Π° Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ Π°Π½ΡƒΠ»ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° опСрация, слСд ΠΊΠ°Ρ‚ΠΎ Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π°Π»Π°, ΠΊΠΎΠ΄ΡŠΡ‚, ΠΊΠΎΠΉΡ‚ΠΎ сС изпълнява, трябва Π΄Π° бъдС изпълнСн с ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π·Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π½Π° CancellationToken. Ако няма ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, Ρ‚ΠΎΠ³Π°Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ Cancel, ΠΈΠ·Π²ΠΈΠΊΠ°Π½ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π° CancellationTokenSource, Ρ‰Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° спрС ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π° само ΠΏΡ€Π΅Π΄ΠΈ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅.

ΠŸΠΎΡΠ»Π΅Π΄Π½ΠΈΡΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ Π΅ ΠΎΠ±Π΅ΠΊΡ‚ Π½Π° ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‡ΠΈΠΊ ΠΎΡ‚ Ρ‚ΠΈΠΏ TaskScheduler. Π’ΠΎΠ·ΠΈ клас ΠΈ Π½Π΅Π³ΠΎΠ²ΠΈΡ‚Π΅ наслСдници са ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈ Π΄Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€Π°Ρ‚ стратСгии Π·Π° разпрСдСлянС Π½Π° Π—Π°Π΄Π°Ρ‡ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ нишки; ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ Π—Π°Π΄Π°Ρ‡Π°Ρ‚Π° Ρ‰Π΅ бъдС изпълнСна Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π½Π° нишка ΠΎΡ‚ ΠΏΡƒΠ»Π°.

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΡŠΡ‚ await сС ΠΏΡ€ΠΈΠ»Π°Π³Π° към ΡΡŠΠ·Π΄Π°Π΄Π΅Π½Π°Ρ‚Π° Π·Π°Π΄Π°Ρ‡Π°, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΊΠΎΠ΄ΡŠΡ‚, написан слСд Π½Π΅Π³ΠΎ, Π°ΠΊΠΎ ΠΈΠΌΠ° Ρ‚Π°ΠΊΡŠΠ², Ρ‰Π΅ бъдС изпълнСн Π² ΡΡŠΡ‰ΠΈΡ контСкст (чСсто Ρ‚ΠΎΠ²Π° ΠΎΠ·Π½Π°Ρ‡Π°Π²Π° Π² ΡΡŠΡ‰Π°Ρ‚Π° нишка) ΠΊΠ°Ρ‚ΠΎ ΠΊΠΎΠ΄Π° ΠΏΡ€Π΅Π΄ΠΈ await.

ΠœΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ Π΅ ΠΌΠ°Ρ€ΠΊΠΈΡ€Π°Π½ ΠΊΠ°Ρ‚ΠΎ async void, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° await, Π½ΠΎ извикващият ΠΊΠΎΠ΄ няма Π΄Π° ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠ·Ρ‡Π°ΠΊΠ° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ. Ако Ρ‚Π°ΠΊΠ°Π²Π° функция Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ°, Ρ‚ΠΎΠ³Π°Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ трябва Π΄Π° Π²ΡŠΡ€Π½Π΅ Task. ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈΡ‚Π΅, ΠΌΠ°Ρ€ΠΊΠΈΡ€Π°Π½ΠΈ ΠΊΠ°Ρ‚ΠΎ async void, са доста чСсто срСщани: ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Ρ‚ΠΎΠ²Π° са ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΠΈ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ работят Π½Π° ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ° Π½Π° ΠΏΠΎΠΆΠ°Ρ€ ΠΈ Π·Π°Π±Ρ€Π°Π²Π°. Ако трябва Π½Π΅ само Π΄Π° Π΄Π°Π΄Π΅Ρ‚Π΅ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π΄Π° ΠΈΠ·Ρ‡Π°ΠΊΠ°Ρ‚Π΅ Π΄ΠΎ края Π½Π° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ, Π½ΠΎ ΠΈ Π΄Π° Π²ΡŠΡ€Π½Π΅Ρ‚Π΅ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π°, Ρ‚ΠΎΠ³Π°Π²Π° трябва Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ Task.

На Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π°, която ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ StartNew Π²ΡŠΡ€Π½Π°, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π½Π° всСки Π΄Ρ€ΡƒΠ³, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·Π²ΠΈΠΊΠ°Ρ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ConfigureAwait с false ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€Π°, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ слСд await Ρ‰Π΅ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈ Π½Π΅ Π²ΡŠΡ€Ρ…Ρƒ заснСтия контСкст, Π° Π²ΡŠΡ€Ρ…Ρƒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½. Π’ΠΎΠ²Π° Π²ΠΈΠ½Π°Π³ΠΈ трябва Π΄Π° сС ΠΏΡ€Π°Π²ΠΈ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ΡŠΡ‚ Π½Π° изпълнСниС Π½Π΅ Π΅ Π²Π°ΠΆΠ΅Π½ Π·Π° ΠΊΠΎΠ΄Π° слСд ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅. Π’ΠΎΠ²Π° ΡΡŠΡ‰ΠΎ Π΅ ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΠΊΠ° ΠΎΡ‚ MS ΠΏΡ€ΠΈ писанС Π½Π° ΠΊΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ бъдС доставСн ΠΎΠΏΠ°ΠΊΠΎΠ²Π°Π½ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°.

НСка сС спрСм ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Π½Π° Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·Ρ‡Π°ΠΊΠ°Ρ‚Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π·Π°Π΄Π°Ρ‡Π°. По-Π΄ΠΎΠ»Ρƒ Π΅ Π΄Π°Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΊΠΎΠ΄ с ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈ ΠΊΠΎΠ³Π° ΠΎΡ‡Π°ΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π΅ Π½Π°ΠΏΡ€Π°Π²Π΅Π½ΠΎ условно Π΄ΠΎΠ±Ρ€Π΅ ΠΈ ΠΊΠΎΠ³Π° Π΅ Π½Π°ΠΏΡ€Π°Π²Π΅Π½ΠΎ условно лошо.

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
}

Π’ ΠΏΡŠΡ€Π²ΠΈΡ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°ΠΌΠ΅ Π—Π°Π΄Π°Ρ‡Π°Ρ‚Π° Π΄Π° Π·Π°Π²ΡŠΡ€ΡˆΠΈ, Π±Π΅Π· Π΄Π° Π±Π»ΠΎΠΊΠΈΡ€Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‰Π°Ρ‚Π° нишка; Ρ‰Π΅ сС Π²ΡŠΡ€Π½Π΅ΠΌ към ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π° само ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π²Π΅Ρ‡Π΅ Π΅ Ρ‚Π°ΠΌ; Π΄ΠΎΡ‚ΠΎΠ³Π°Π²Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‰Π°Ρ‚Π° нишка Π΅ оставСна Π½Π° собствСнитС си устройства.

Π’ΡŠΠ² втория Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€Π°ΠΌΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‰Π°Ρ‚Π° нишка, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π½Π΅ сС изчисли Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. Π’ΠΎΠ²Π° Π΅ лошо Π½Π΅ само Π·Π°Ρ‰ΠΎΡ‚ΠΎ смС Π·Π°Π΅Π»ΠΈ нишка, Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° Ρ†Π΅Π½Π΅Π½ рСсурс Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, с просто бСздСйствиС, Π½ΠΎ ΠΈ Π·Π°Ρ‰ΠΎΡ‚ΠΎ Π°ΠΊΠΎ ΠΊΠΎΠ΄ΡŠΡ‚ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π°ΠΌΠ΅, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° await ΠΈ ΠΊΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ΡŠΡ‚ Π½Π° синхронизация изисква Π²Ρ€ΡŠΡ‰Π°Π½Π΅ към ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‰Π°Ρ‚Π° нишка слСд await, Ρ‚ΠΎΠ³Π°Π²Π° Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ задънСна ΡƒΠ»ΠΈΡ†Π°: ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‰Π°Ρ‚Π° нишка Ρ‡Π°ΠΊΠ° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ ΠΎΡ‚ асинхронния ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΄Π° бъдС изчислСн, асинхронният ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π°ΠΏΡ€Π°Π·Π½ΠΎ сС ΠΎΠΏΠΈΡ‚Π²Π° Π΄Π° ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ си Π² ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‰Π°Ρ‚Π° нишка.

Π”Ρ€ΡƒΠ³ Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΠΊ Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π΅ слоТното ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π°Π½Π΅ Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ. Π€Π°ΠΊΡ‚ Π΅, Ρ‡Π΅ Π³Ρ€Π΅ΡˆΠΊΠΈΡ‚Π΅ Π² асинхронния ΠΊΠΎΠ΄ ΠΏΡ€ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° async/await са ΠΌΠ½ΠΎΠ³ΠΎ лСсни Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° - Ρ‚Π΅ сС Π΄ΡŠΡ€ΠΆΠ°Ρ‚ ΠΏΠΎ ΡΡŠΡ‰ΠΈΡ Π½Π°Ρ‡ΠΈΠ½, ΠΊΠ°ΠΊΡ‚ΠΎ Π°ΠΊΠΎ ΠΊΠΎΠ΄ΡŠΡ‚ Π΅ синхронСн. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‡Π΅, Π°ΠΊΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠΌ Π΅ΠΊΠ·ΠΎΡ€ΡΠΈΠ·ΡŠΠΌ Π½Π° синхронно ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅ към Π·Π°Π΄Π°Ρ‡Π°, ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎΡ‚ΠΎ ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ сС ΠΏΡ€Π΅Π²Ρ€ΡŠΡ‰Π° Π² AggregateException, Ρ‚.Π΅. Π—Π° Π΄Π° сС справитС с ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅Ρ‚ΠΎ, Ρ‰Π΅ трябва Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ‚Π΅ Ρ‚ΠΈΠΏΠ° InnerException ΠΈ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ сами if Π²Π΅Ρ€ΠΈΠ³Π° Π²ΡŠΡ‚Ρ€Π΅ Π² Π΅Π΄ΠΈΠ½ catch Π±Π»ΠΎΠΊ ΠΈΠ»ΠΈ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ конструкцията catch when, вмСсто Π²Π΅Ρ€ΠΈΠ³Π°Ρ‚Π° ΠΎΡ‚ catch Π±Π»ΠΎΠΊΠΎΠ²Π΅, която Π΅ ΠΏΠΎ-ΠΏΠΎΠ·Π½Π°Ρ‚Π° Π² свСта Π½Π° C#.

ВрСтият ΠΈ послСдСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΡΡŠΡ‰ΠΎ са ΠΌΠ°Ρ€ΠΊΠΈΡ€Π°Π½ΠΈ ΠΊΠ°Ρ‚ΠΎ лоши ΠΏΠΎ ΡΡŠΡ‰Π°Ρ‚Π° ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° ΠΈ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‚ всички ΡΡŠΡ‰ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ.

ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈΡ‚Π΅ WhenAny ΠΈ WhenAll са ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΈ Π·Π° ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅ Π½Π° Π³Ρ€ΡƒΠΏΠ° ΠΎΡ‚ Π·Π°Π΄Π°Ρ‡ΠΈ; Ρ‚Π΅ ΠΎΠ±Π³Ρ€ΡŠΡ‰Π°Ρ‚ Π³Ρ€ΡƒΠΏΠ° ΠΎΡ‚ Π·Π°Π΄Π°Ρ‡ΠΈ Π² Π΅Π΄Π½Π°, която Ρ‰Π΅ сС задСйства ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π·Π°Π΄Π°Ρ‡Π° ΠΎΡ‚ Π³Ρ€ΡƒΠΏΠ°Ρ‚Π° бъдС задСйствана Π·Π° ΠΏΡŠΡ€Π²ΠΈ ΠΏΡŠΡ‚, ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π°Ρ‚ΠΎ всички Ρ‚Π΅ са Π·Π°Π²ΡŠΡ€ΡˆΠΈΠ»ΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ си.

Π‘ΠΏΠΈΡ€Π°Π½Π΅ Π½Π° нишки

ΠŸΠΎΡ€Π°Π΄ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°Π»ΠΎΠΆΠΈ спиранС Π½Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°, слСд ΠΊΠ°Ρ‚ΠΎ Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π°Π». Има няколко Π½Π°Ρ‡ΠΈΠ½Π° Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Ρ‚ΠΎΠ²Π°. ΠšΠ»Π°ΡΡŠΡ‚ Thread ΠΈΠΌΠ° Π΄Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° с подходящи ΠΈΠΌΠ΅Π½Π°: ΠŸΡ€Π΅ΠΊΡ€Π°Ρ‚ΡΠ²Π°Π½Π΅ ΠΈ ΠŸΡ€Π΅ΠΊΡŠΡΠ²Π°Π½Π΅. ΠŸΡŠΡ€Π²ΠΈΡΡ‚ силно Π½Π΅ сС ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡Π²Π° Π·Π° ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π°, Ρ‚.ΠΊ слСд ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ във всСки ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° всяка инструкция, Ρ‰Π΅ бъдС Ρ…Π²ΡŠΡ€Π»Π΅Π½ΠΎ ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ThreadAbortedException. НС ΠΎΡ‡Π°ΠΊΠ²Π°Ρ‚Π΅ Ρ‚Π°ΠΊΠΎΠ²Π° ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π΄Π° бъдС Ρ…Π²ΡŠΡ€Π»Π΅Π½ΠΎ ΠΏΡ€ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡Π°Π²Π°Π½Π΅ Π½Π° която ΠΈ Π΄Π° Π΅ цСлочислСна ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π°, Π½Π°Π»ΠΈ? И ΠΊΠΎΠ³Π°Ρ‚ΠΎ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄, Ρ‚ΠΎΠ²Π° Π΅ съвсСм Ρ€Π΅Π°Π»Π½Π° ситуация. Ако трябва Π΄Π° ΠΏΠΎΠΏΡ€Π΅Ρ‡ΠΈΡ‚Π΅ Π½Π° CLR Π΄Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° Ρ‚Π°ΠΊΠΎΠ²Π° ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Ρ€Π°Π·Π΄Π΅Π» ΠΎΡ‚ ΠΊΠΎΠ΄Π°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΎ ΠΎΠ±Π²ΠΈΠ΅Ρ‚Π΅ Π² извиквания Thread.BeginCriticalRegion, Thread.EndCriticalRegion. ВсСки ΠΊΠΎΠ΄, написан Π² Π±Π»ΠΎΠΊ finally, Π΅ ΠΎΠ±Π²ΠΈΡ‚ Π² Ρ‚Π°ΠΊΠΈΠ²Π° извиквания. ΠŸΠΎΡ€Π°Π΄ΠΈ Ρ‚Π°Π·ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π² Π΄ΡŠΠ»Π±ΠΈΠ½ΠΈΡ‚Π΅ Π½Π° ΠΊΠΎΠ΄Π° Π½Π° Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π±Π»ΠΎΠΊΠΎΠ²Π΅ с ΠΏΡ€Π°Π·Π΅Π½ ΠΎΠΏΠΈΡ‚, Π½ΠΎ Π½Π΅ ΠΈ ΠΏΡ€Π°Π·Π΅Π½ Ρ„ΠΈΠ½Π°Π». Microsoft ΠΎΠ±Π΅Π·ΡΡŠΡ€Ρ‡Π°Π²Π° Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΌΠ½ΠΎΠ³ΠΎ, Ρ‡Π΅ Π½Π΅ Π³ΠΎ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ…Π° Π² .net core.

ΠœΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ Interrupt Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΏΠΎ-ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ΠΈΠΌΠΎ. МоТС Π΄Π° ΠΏΡ€Π΅ΠΊΡŠΡΠ½Π΅ Π½ΠΈΡˆΠΊΠ°Ρ‚Π° с ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ThreadInterruptedException само Π² ΠΎΠ½Π΅Π·ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΈ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π½ΠΈΡˆΠΊΠ°Ρ‚Π° Π΅ Π² ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ Π½Π° ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅. Π’ΠΎΠΉ Π²Π»ΠΈΠ·Π° Π² Ρ‚ΠΎΠ²Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ виси, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Ρ‡Π°ΠΊΠ° WaitHandle, Π·Π°ΠΊΠ»ΡŽΡ‡Π²Π°Π½Π΅ ΠΈΠ»ΠΈ слСд ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° Thread.Sleep.

И Π΄Π²Π°Ρ‚Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°, описани ΠΏΠΎ-Π³ΠΎΡ€Π΅, са лоши ΠΏΠΎΡ€Π°Π΄ΠΈ тяхната нСпрСдсказуСмост. Π Π΅ΡˆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° структура CancellationToken ΠΈ класа CancellationTokenSource. Π’ΡŠΠΏΡ€ΠΎΡΡŠΡ‚ Π΅ слСдният: създава сС СкзСмпляр Π½Π° класа CancellationTokenSource ΠΈ само Ρ‚ΠΎΠ·ΠΈ, ΠΊΠΎΠΉΡ‚ΠΎ Π³ΠΎ ΠΏΡ€ΠΈΡ‚Π΅ΠΆΠ°Π²Π°, ΠΌΠΎΠΆΠ΅ Π΄Π° спрС опСрацията, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·Π²ΠΈΠΊΠ° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠžΡ‚ΠΊΠ°Π·. Π‘Π°ΠΌΠΎ CancellationToken сС ΠΏΡ€Π΅Π΄Π°Π²Π° Π½Π° самата опСрация. БобствСницитС Π½Π° CancellationToken Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ сами Π΄Π° отмСнят опСрацията, Π° ΠΌΠΎΠ³Π°Ρ‚ само Π΄Π° провСрят Π΄Π°Π»ΠΈ опСрацията Π΅ Π±ΠΈΠ»Π° ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°. Π—Π° Ρ‚ΠΎΠ²Π° ΠΈΠΌΠ° Π±ΡƒΠ»Π΅Π²ΠΎ свойство IsCancellationRequested ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ ThrowIfCancelRequested. ΠŸΠΎΡΠ»Π΅Π΄Π½ΠΎΡ‚ΠΎ Ρ‰Π΅ Ρ…Π²ΡŠΡ€Π»ΠΈ ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ TaskCancelledException Π°ΠΊΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ Cancel Π΅ Π±ΠΈΠ» ΠΈΠ·Π²ΠΈΠΊΠ°Π½ Π½Π° СкзСмпляра CancellationToken, ΠΊΠΎΠΉΡ‚ΠΎ сС ΠΊΠΎΠΏΠΈΡ€Π°. И Ρ‚ΠΎΠ²Π° Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡Π²Π°ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅. Π’ΠΎΠ²Π° Π΅ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π΅Π½ΠΈΠ΅ Π² сравнСниС с ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ ΠΎΠΏΡ†ΠΈΠΈ Ρ‡Ρ€Π΅Π· ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° пълСн ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» Π²ΡŠΡ€Ρ…Ρƒ Ρ‚ΠΎΠ²Π° Π² ΠΊΠΎΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ опСрацията ΠΏΠΎ ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚Π΅Π½Π°.

Най-Π±Ρ€ΡƒΡ‚Π°Π»Π½Π°Ρ‚Π° опция Π·Π° спиранС Π½Π° нишка Π΅ Π΄Π° сС ΠΈΠ·Π²ΠΈΠΊΠ° функцията TerminateThread Π½Π° Win32 API. ΠŸΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° CLR слСд ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° Ρ‚Π°Π·ΠΈ функция ΠΌΠΎΠΆΠ΅ Π΄Π° Π΅ Π½Π΅ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ΠΈΠΌΠΎ. Π’ MSDN Π΅ написано слСдното Π·Π° Ρ‚Π°Π·ΠΈ функция: β€žTerminateThread Π΅ опасна функция, която трябва Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° само Π² Π½Π°ΠΉ-ΠΊΡ€Π°ΠΉΠ½ΠΈΡ‚Π΅ случаи. β€œ

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Π½Π΅ Π½Π° наслСдСн API Π² Π±Π°Π·ΠΈΡ€Π°Π½ Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° FromAsync

Ако ΠΈΠΌΠ°Ρ‚Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ ΠΊΡŠΡΠΌΠ΅Ρ‚ Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π°Ρ‚ слСд Π²ΡŠΠ²Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° Tasks ΠΈ Π΅ прСстанал Π΄Π° ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ²Π° Ρ‚ΠΈΡ… уТас Π·Π° ΠΏΠΎΠ²Π΅Ρ‡Π΅Ρ‚ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ, Ρ‚ΠΎΠ³Π°Π²Π° няма Π΄Π° сС Π½Π°Π»Π°Π³Π° Π΄Π° сС справятС с ΠΌΠ½ΠΎΠ³ΠΎ стари API, ΠΊΠ°ΠΊΡ‚ΠΎ Π½Π° Ρ‚Ρ€Π΅Ρ‚ΠΈ страни, Ρ‚Π°ΠΊΠ° ΠΈ Π½Π° вашия Π΅ΠΊΠΈΠΏ Π΅ ΠΈΠ·ΠΌΡŠΡ‡Π²Π°Π» Π² ΠΌΠΈΠ½Π°Π»ΠΎΡ‚ΠΎ. Π—Π° щастиС Π΅ΠΊΠΈΠΏΡŠΡ‚ Π½Π° .NET Framework сС ΠΏΠΎΠ³Ρ€ΠΈΠΆΠΈ Π·Π° нас, ΠΌΠ°ΠΊΠ°Ρ€ Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ Π±ΠΈ Ρ†Π΅Π»Ρ‚Π° бСшС Π΄Π° сС ΠΏΠΎΠ³Ρ€ΠΈΠΆΠΈΠΌ Π·Π° сСбС си. ΠšΠ°ΠΊΡ‚ΠΎ ΠΈ Π΄Π° Π΅, .NET Ρ€Π°Π·ΠΏΠΎΠ»Π°Π³Π° с Ρ€Π΅Π΄ΠΈΡ†Π° инструмСнти Π·Π° Π±Π΅Π·Π±ΠΎΠ»Π΅Π·Π½Π΅Π½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄, написан Π² стари ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈ Π·Π° асинхронно ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅, към новия. Π•Π΄ΠΈΠ½ ΠΎΡ‚ тях Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ FromAsync Π½Π° TaskFactory. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° ΠΊΠΎΠ΄Π° ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ ΠΎΠ±Π²ΠΈΠ²Π°ΠΌ старитС асинхронни ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π½Π° класа WebRequest Π² Task, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄.

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

Π’ΠΎΠ²Π° Π΅ само ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈ Π΅Π΄Π²Π° Π»ΠΈ Ρ‰Π΅ трябва Π΄Π° ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ Ρ‚ΠΎΠ²Π° с Π²Π³Ρ€Π°Π΄Π΅Π½ΠΈ Ρ‚ΠΈΠΏΠΎΠ²Π΅, Π½ΠΎ всСки стар ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ просто гъмТи ΠΎΡ‚ BeginDoSomething ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ Π²Ρ€ΡŠΡ‰Π°Ρ‚ IAsyncResult ΠΈ EndDoSomething ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ Π³ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Ρ‚.

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°ΠΉΡ‚Π΅ наслСдСния API Π² Π±Π°Π·ΠΈΡ€Π°Π½ Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° класа TaskCompletionSource

Π”Ρ€ΡƒΠ³ Π²Π°ΠΆΠ΅Π½ инструмСнт, ΠΊΠΎΠΉΡ‚ΠΎ трябва Π΄Π° ΠΈΠΌΠ°Ρ‚Π΅ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄, Π΅ ΠΊΠ»Π°ΡΡŠΡ‚ TaskCompletionSource. ΠžΡ‚ Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΈ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ° Π½Π° Ρ€Π°Π±ΠΎΡ‚Π°, Ρ‚ΠΎΠΉ ΠΌΠΎΠΆΠ΅ Π΄Π° напомня донякъдС Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° RegisterWaitForSingleObject Π½Π° класа ThreadPool, Π·Π° ΠΊΠΎΠΉΡ‚ΠΎ писах ΠΏΠΎ-Π³ΠΎΡ€Π΅. Използвайки Ρ‚ΠΎΠ·ΠΈ клас, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ лСсно ΠΈ ΡƒΠ΄ΠΎΠ±Π½ΠΎ Π΄Π° ΠΎΠΏΠ°ΠΊΠΎΠ²Π°Ρ‚Π΅ стари асинхронни API Π² Π—Π°Π΄Π°Ρ‡ΠΈ.

Π©Π΅ ΠΊΠ°ΠΆΠ΅Ρ‚Π΅, Ρ‡Π΅ Π²Π΅Ρ‡Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ… Π·Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° FromAsync Π½Π° класа TaskFactory, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ Π·Π° Ρ‚Π΅Π·ΠΈ Ρ†Π΅Π»ΠΈ. Π’ΡƒΠΊ Ρ‰Π΅ трябва Π΄Π° си ΠΏΡ€ΠΈΠΏΠΎΠΌΠ½ΠΈΠΌ цялата история Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° асинхронни ΠΌΠΎΠ΄Π΅Π»ΠΈ Π² .net, ΠΊΠΎΠΈΡ‚ΠΎ Microsoft ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈ ΠΏΡ€Π΅Π· послСднитС 15 Π³ΠΎΠ΄ΠΈΠ½ΠΈ: ΠΏΡ€Π΅Π΄ΠΈ Task-Based Asynchronous Pattern (TAP), имашС Asynchronous Programming Pattern (APP), ΠΊΠΎΠΉΡ‚ΠΎ бСшС Π·Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ ЗапочнСтСНаправСтС Π½Π΅Ρ‰ΠΎ, ΠΊΠΎΠ΅Ρ‚ΠΎ сС Π²Ρ€ΡŠΡ‰Π° IAsyncResult ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ ΠšΡ€Π°ΠΉDoSomething, ΠΊΠΎΠΉΡ‚ΠΎ Π³ΠΎ ΠΏΡ€ΠΈΠ΅ΠΌΠ° ΠΈ Π·Π° наслСдството ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ Π³ΠΎΠ΄ΠΈΠ½ΠΈ, ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ FromAsync Π΅ просто ΠΏΠ΅Ρ€Ρ„Π΅ΠΊΡ‚Π΅Π½, Π½ΠΎ с Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Ρ‚ΠΎΠΉ бСшС Π·Π°ΠΌΠ΅Π½Π΅Π½ ΠΎΡ‚ базирания Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ асинхронСн ΠΌΠΎΠ΄Π΅Π» (EAP), ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°, Ρ‡Π΅ Ρ‰Π΅ бъдС ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ°Π½ΠΎ ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅, ΠΊΠΎΠ³Π°Ρ‚ΠΎ асинхронната опСрация Π·Π°Π²ΡŠΡ€ΡˆΠΈ.

TaskCompletionSource Π΅ ΠΈΠ΄Π΅Π°Π»Π΅Π½ Π·Π° ΠΎΠ±Π²ΠΈΠ²Π°Π½Π΅ Π½Π° Tasks ΠΈ наслСдСни API, ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½ΠΈ ΠΎΠΊΠΎΠ»ΠΎ ΠΌΠΎΠ΄Π΅Π»Π° Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ. Π‘ΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° Π½Π° Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Π° Π΅ слСдната: ΠΎΠ±Π΅ΠΊΡ‚ ΠΎΡ‚ Ρ‚ΠΎΠ·ΠΈ клас ΠΈΠΌΠ° ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎ свойство ΠΎΡ‚ Ρ‚ΠΈΠΏ Task, Ρ‡ΠΈΠ΅Ρ‚ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€Π° Ρ‡Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΡ‚Π΅ SetResult, SetException ΠΈ Π΄Ρ€. Π½Π° класа TaskCompletionSource. На мСста, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΡŠΡ‚ Π·Π° ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅ Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ към Ρ‚Π°Π·ΠΈ Π·Π°Π΄Π°Ρ‡Π°, тя Ρ‰Π΅ бъдС изпълнСна ΠΈΠ»ΠΈ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½Π° с ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² зависимост ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ към TaskCompletionSource. Ако всС ΠΎΡ‰Π΅ Π½Π΅ Π΅ ясно, Π½Π΅ΠΊΠ° Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с ΠΊΠΎΠ΄, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ някакъв стар EAP API Π΅ ΠΎΠ±Π²ΠΈΡ‚ Π² Π·Π°Π΄Π°Ρ‡Π° с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° TaskCompletionSource: ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ сС задСйства, Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π° Ρ‰Π΅ бъдС ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»Π΅Π½Π° Π² ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ Completed ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠ» ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° await към Ρ‚Π°Π·ΠΈ Π—Π°Π΄Π°Ρ‡Π° Ρ‰Π΅ възобнови ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ си слСд ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚.

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

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

    result completionSource.Task;
}

TaskCompletionSource Π‘ΡŠΠ²Π΅Ρ‚ΠΈ ΠΈ Ρ‚Ρ€ΠΈΠΊΠΎΠ²Π΅

ΠžΠΏΠ°ΠΊΠΎΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° стари API Π½Π΅ Π΅ всичко, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° TaskCompletionSource. Π˜Π·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ клас отваря интСрСсна Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€Π°Π½Π΅ Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ API Π·Π° Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ Π·Π°Π΅ΠΌΠ°Ρ‚ нишки. А ΠΏΠΎΡ‚ΠΎΠΊΡŠΡ‚, ΠΊΠ°ΠΊΡ‚ΠΎ си спомнямС, Π΅ скъп рСсурс ΠΈ тСхният Π±Ρ€ΠΎΠΉ Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ (Π³Π»Π°Π²Π½ΠΎ ΠΎΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π½Π° RAM). Π’ΠΎΠ²Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ лСсно Π΄Π° бъдС постигнато Ρ‡Ρ€Π΅Π· Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π²Π°Π½Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π° Π·Π°Ρ€Π΅Π΄Π΅Π½ΠΎ ΡƒΠ΅Π± ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ със слоТна бизнСс Π»ΠΎΠ³ΠΈΠΊΠ°. НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΠΈΡ‚Π΅, Π·Π° ΠΊΠΎΠΈΡ‚ΠΎ говоря, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΏΡ€ΠΈΠ»Π°Π³Π°ΠΌΠ΅ Ρ‚Π°ΠΊΡŠΠ² Ρ‚Ρ€ΠΈΠΊ ΠΊΠ°Ρ‚ΠΎ Long-Polling.

Накратко, ΡΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° Π½Π° Ρ‚Ρ€ΠΈΠΊΠ° Π΅ слСдната: трябва Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ информация ΠΎΡ‚ API Π·Π° някои ΡΡŠΠ±ΠΈΡ‚ΠΈΡ, случващи сС ΠΎΡ‚ Π½Π΅Π³ΠΎΠ²Π° страна, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ API ΠΏΠΎ някаква ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° Π΄ΠΎΠΊΠ»Π°Π΄Π²Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ, Π° ΠΌΠΎΠΆΠ΅ само Π΄Π° Π²ΡŠΡ€Π½Π΅ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° Ρ‚ΠΎΠ²Π° са всички API, ΠΈΠ·Π³Ρ€Π°Π΄Π΅Π½ΠΈ Π²ΡŠΡ€Ρ…Ρƒ HTTP ΠΏΡ€Π΅Π΄ΠΈ Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° WebSocket ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π΅ Π±ΠΈΠ»ΠΎ нСвъзмоТно ΠΏΠΎ някаква ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ρ‚Π°Π·ΠΈ тСхнология. ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΠΎΠΏΠΈΡ‚Π° HTTP ΡΡŠΡ€Π²ΡŠΡ€Π°. HTTP ΡΡŠΡ€Π²ΡŠΡ€ΡŠΡ‚ Π½Π΅ ΠΌΠΎΠΆΠ΅ сам Π΄Π° ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€Π° комуникация с ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π•Π΄Π½ΠΎ просто Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π΅ Π΄Π° сС Π·Π°ΠΏΠΈΡ‚Π²Π° ΡΡŠΡ€Π²ΡŠΡ€ΡŠΡ‚ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Ρ‚Π°ΠΉΠΌΠ΅Ρ€, Π½ΠΎ Ρ‚ΠΎΠ²Π° създава Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅ Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π° ΠΈ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ забавянС Π½Π° срСдния TimerInterval / 2. Π—Π° Π΄Π° сС Π·Π°ΠΎΠ±ΠΈΠΊΠΎΠ»ΠΈ Ρ‚ΠΎΠ²Π°, бСшС измислСн Ρ‚Ρ€ΠΈΠΊ, Π½Π°Ρ€Π΅Ρ‡Π΅Π½ Long Polling, ΠΊΠΎΠΉΡ‚ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π²Π° забавянС Π½Π° ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€Π° ΠΎΡ‚ ΡΡŠΡ€Π²ΡŠΡ€Π°, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π·Π° ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅ ΠΈΠ·Ρ‚Π΅Ρ‡Π΅ ΠΈΠ»ΠΈ сС случи ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅. Ако ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ Π΅ Π½Π°ΡΡ‚ΡŠΠΏΠΈΠ»ΠΎ, Ρ‚ΠΎ сС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π°, Π°ΠΊΠΎ Π½Π΅, Ρ‚ΠΎΠ³Π°Π²Π° заявката сС ΠΈΠ·ΠΏΡ€Π°Ρ‰Π° ΠΎΡ‚Π½ΠΎΠ²ΠΎ.

while(!eventOccures && !timeoutExceeded)  {

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

Но Ρ‚Π°ΠΊΠΎΠ²Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Ρ‰Π΅ сС ΠΎΠΊΠ°ΠΆΠ΅ уТасно, Ρ‰ΠΎΠΌ броят Π½Π° Ρ‡Π°ΠΊΠ°Ρ‰ΠΈΡ‚Π΅ Π·Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΈ сС ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈ, Π·Π°Ρ‰ΠΎΡ‚ΠΎ... ВсСки Ρ‚Π°ΠΊΡŠΠ² ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°Π΅ΠΌΠ° цяла нишка Π² ΠΎΡ‡Π°ΠΊΠ²Π°Π½Π΅ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅. Π”Π°, ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΎ забавянС ΠΎΡ‚ 1ms, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ сС задСйства, Π½Π°ΠΉ-чСсто Ρ‚ΠΎΠ²Π° Π½Π΅ Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ, Π½ΠΎ Π·Π°Ρ‰ΠΎ Π΄Π° ΠΏΡ€Π°Π²ΠΈΠΌ софтуСра ΠΏΠΎ-лош, ΠΎΡ‚ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС? Ако ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π΅ΠΌ Thread.Sleep(1), Ρ‚ΠΎΠ³Π°Π²Π° Π½Π°ΠΏΡ€Π°Π·Π½ΠΎ Ρ‰Π΅ Π·Π°Ρ€Π΅Π΄ΠΈΠΌ Π΅Π΄Π½ΠΎ процСсорно ядро ​​на 100% ΠΏΡ€Π°Π·Π΅Π½ Ρ…ΠΎΠ΄, Π²ΡŠΡ€Ρ‚ΡΡ‰ΠΎ сС Π² Π±Π΅Π·ΠΏΠΎΠ»Π΅Π·Π΅Π½ Ρ†ΠΈΠΊΡŠΠ». Π‘ ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° TaskCompletionSource ΠΌΠΎΠΆΠ΅Ρ‚Π΅ лСсно Π΄Π° ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈΡ‚Π΅ Ρ‚ΠΎΠ·ΠΈ ΠΊΠΎΠ΄ ΠΈ Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚Π΅ всички ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ, посочСни ΠΏΠΎ-Π³ΠΎΡ€Π΅:

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

Π’ΠΎΠ·ΠΈ ΠΊΠΎΠ΄ Π½Π΅ Π΅ Π³ΠΎΡ‚ΠΎΠ² Π·Π° производство, Π° Π΅ само дСмонстрация. Π—Π° Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ Π² Ρ€Π΅Π°Π»Π½ΠΈ случаи, Π²ΠΈΠ΅ ΡΡŠΡ‰ΠΎ трябва, ΠΊΠ°Ρ‚ΠΎ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ, Π΄Π° сС справитС със ситуацията, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ пристигнС Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π½ΠΈΠΊΠΎΠΉ Π½Π΅ Π³ΠΎ ΠΎΡ‡Π°ΠΊΠ²Π°: Π² Ρ‚ΠΎΠ·ΠΈ случай ΠΌΠ΅Ρ‚ΠΎΠ΄ΡŠΡ‚ AsseptMessageAsync трябва Π΄Π° Π²ΡŠΡ€Π½Π΅ Π²Π΅Ρ‡Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠ΅Π½Π° Π·Π°Π΄Π°Ρ‡Π°. Ако Ρ‚ΠΎΠ²Π° Π΅ Π½Π°ΠΉ-чСсто срСщаният случай, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° помислитС Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ValueTask.

ΠšΠΎΠ³Π°Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ заявка Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅, създавамС ΠΈ поставямС TaskCompletionSource Π² Ρ€Π΅Ρ‡Π½ΠΈΠΊΠ° ΠΈ слСд Ρ‚ΠΎΠ²Π° ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ Ρ‰Π΅ сС случи ΠΏΡŠΡ€Π²ΠΎ: посочСният ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π» ΠΎΡ‚ Π²Ρ€Π΅ΠΌΠ΅ ΠΈΠ·Ρ‚ΠΈΡ‡Π° ΠΈΠ»ΠΈ сС ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅.

ValueTask: Π·Π°Ρ‰ΠΎ ΠΈ ΠΊΠ°ΠΊ

ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ async/await, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° yield return, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ‚ state machine ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈ Ρ‚ΠΎΠ²Π° Π΅ ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π½ΠΎΠ² ΠΎΠ±Π΅ΠΊΡ‚, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΏΠΎΡ‡Ρ‚ΠΈ Π²ΠΈΠ½Π°Π³ΠΈ Π½Π΅ Π΅ Π²Π°ΠΆΠ½ΠΎ, Π½ΠΎ Π² Ρ€Π΅Π΄ΠΊΠΈ случаи ΠΌΠΎΠΆΠ΅ Π΄Π° създадС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ. Π’ΠΎΠ·ΠΈ случай ΠΌΠΎΠΆΠ΅ Π΄Π° Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΊΠΎΠΉΡ‚ΠΎ сС ΠΈΠ·Π²ΠΈΠΊΠ²Π° наистина чСсто, Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π·Π° дСсСтки ΠΈ стотици хиляди обаТдания Π² сСкунда. Ако Ρ‚Π°ΠΊΡŠΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΅ написан ΠΏΠΎ Ρ‚Π°ΠΊΡŠΠ² Π½Π°Ρ‡ΠΈΠ½, Ρ‡Π΅ Π² ΠΏΠΎΠ²Π΅Ρ‡Π΅Ρ‚ΠΎ случаи Π²Ρ€ΡŠΡ‰Π° Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚, заобикаляйки всички Ρ‡Π°ΠΊΠ°Ρ‰ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ, Ρ‚ΠΎΠ³Π°Π²Π° .NET прСдоставя инструмСнт Π·Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° Ρ‚ΠΎΠ²Π° - структурата ValueTask. Π—Π° Π΄Π° станС ясно, Π½Π΅ΠΊΠ° Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ: ΠΈΠΌΠ° кСш, ΠΊΠΎΠΉΡ‚ΠΎ посСщавамС ΠΌΠ½ΠΎΠ³ΠΎ чСсто. Π’ Π½Π΅Π³ΠΎ ΠΈΠΌΠ° някои стойности ΠΈ слСд Ρ‚ΠΎΠ²Π° просто Π³ΠΈ Π²Ρ€ΡŠΡ‰Π°ΠΌΠ΅; Π°ΠΊΠΎ Π½Π΅, Ρ‚ΠΎΠ³Π°Π²Π° ΠΎΡ‚ΠΈΠ²Π°ΠΌΠ΅ Π½Π° някакъв Π±Π°Π²Π΅Π½ IO, Π·Π° Π΄Π° Π³ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ. Искам Π΄Π° направя послСдното асинхронно, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ цСлият ΠΌΠ΅Ρ‚ΠΎΠ΄ сС ΠΎΠΊΠ°Π·Π²Π° асинхронСн. По Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½ очСвидният Π½Π°Ρ‡ΠΈΠ½ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π΅ слСдният:

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

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

ΠŸΠΎΡ€Π°Π΄ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠ΅Ρ‚ΠΎ Π΄Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Ρ‚Π΅ ΠΌΠ°Π»ΠΊΠΎ ΠΈ Π»Π΅ΠΊ страх ΠΎΡ‚ Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊΠ²ΠΎ Ρ‰Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° Roslyn ΠΏΡ€ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΊΠΎΠ΄, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€Π΅Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠ°ΠΊΡ‚ΠΎ слСдва:

public Task<string> GetById(int id) {

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

Наистина, ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΎΡ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π² Ρ‚ΠΎΠ·ΠΈ случай Π±ΠΈ Π±ΠΈΠ»ΠΎ Π΄Π° сС ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π° горСщият ΠΏΡŠΡ‚, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° стойност ΠΎΡ‚ Ρ€Π΅Ρ‡Π½ΠΈΠΊΠ° Π±Π΅Π· Π½Π΅Π½ΡƒΠΆΠ½ΠΈ разпрСдСлСния ΠΈ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅ Π½Π° GC, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π² ΠΎΠ½Π΅Π·ΠΈ Ρ€Π΅Π΄ΠΊΠΈ случаи, ΠΊΠΎΠ³Π°Ρ‚ΠΎ всС ΠΎΡ‰Π΅ трябва Π΄Π° ΠΎΡ‚ΠΈΠ΄Π΅ΠΌ Π½Π° IO Π·Π° Π΄Π°Π½Π½ΠΈ , всичко Ρ‰Π΅ останС плюс/минус ΠΏΠΎ стария Π½Π°Ρ‡ΠΈΠ½:

public ValueTask<string> GetById(int id) {

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

НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎ-ΠΎΡ‚Π±Π»ΠΈΠ·ΠΎ Ρ‚Π°Π·ΠΈ част ΠΎΡ‚ ΠΊΠΎΠ΄Π°: Π°ΠΊΠΎ ΠΈΠΌΠ° стойност Π² кСша, Π½ΠΈΠ΅ създавамС структура, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π΅Π½ случай истинската Π·Π°Π΄Π°Ρ‡Π° Ρ‰Π΅ бъдС ΠΎΠ±Π²ΠΈΡ‚Π° Π² смислСна. Π˜Π·Π²ΠΈΠΊΠ²Π°Ρ‰ΠΈΡΡ‚ ΠΊΠΎΠ΄ Π½Π΅ сС интСрСсува Π² ΠΊΠΎΠΉ ΠΏΡŠΡ‚ Π΅ Π±ΠΈΠ» изпълнСн Ρ‚ΠΎΠ·ΠΈ ΠΊΠΎΠ΄: ValueTask, ΠΎΡ‚ Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° синтаксиса Π½Π° C#, Ρ‰Π΅ сС Π΄ΡŠΡ€ΠΆΠΈ ΠΏΠΎ ΡΡŠΡ‰ΠΈΡ Π½Π°Ρ‡ΠΈΠ½ ΠΊΠ°Ρ‚ΠΎ ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½Π° Π·Π°Π΄Π°Ρ‡Π° Π² Ρ‚ΠΎΠ·ΠΈ случай.

TaskSchedulers: ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° стратСгии Π·Π° стартиранС Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈ

БлСдващият API, ΠΊΠΎΠΉΡ‚ΠΎ Π±ΠΈΡ… искал Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌ, Π΅ ΠΊΠ»Π°ΡΡŠΡ‚ Task Scheduler ΠΈ Π½Π΅Π³ΠΎΠ²ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΠΈ. Π’Π΅Ρ‡Π΅ спомСнах ΠΏΠΎ-Π³ΠΎΡ€Π΅, Ρ‡Π΅ TPL ΠΈΠΌΠ° способността Π΄Π° управлява стратСгии Π·Π° разпрСдСлянС Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈ Π² нишки. Π’Π°ΠΊΠΈΠ²Π° стратСгии са Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π½ΠΈ Π² наслСдницитС Π½Π° класа TaskScheduler. ΠŸΠΎΡ‡Ρ‚ΠΈ всяка стратСгия, ΠΎΡ‚ която ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½ΡƒΠΆΠ΄Π°Π΅Ρ‚Π΅, ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π° Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π°. ParallelExtensionsExtras, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΎΡ‚ Microsoft, Π½ΠΎ Π½Π΅ Π΅ част ΠΎΡ‚ .NET, Π° сС доставя ΠΊΠ°Ρ‚ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚ Nuget. НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π½Π°ΠΊΡ€Π°Ρ‚ΠΊΠΎ някои ΠΎΡ‚ тях:

  • CurrentThreadTaskScheduler β€” изпълнява Π·Π°Π΄Π°Ρ‡ΠΈ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° нишка
  • LimitedConcurrencyLevelTaskScheduler β€” ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π°Π²Π° броя Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅, изпълнявани Π΅Π΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Ρ‡Ρ€Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ N, ΠΊΠΎΠΉΡ‚ΠΎ сС ΠΏΡ€ΠΈΠ΅ΠΌΠ° Π² конструктора
  • OrderedTaskScheduler β€” сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π° ΠΊΠ°Ρ‚ΠΎ LimitedConcurrencyLevelTaskScheduler(1), Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅ Ρ‰Π΅ сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ послСдоватСлно.
  • WorkStealingTaskScheduler - инструмСнти ΠΊΡ€Π°ΠΆΠ±Π° Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ към Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅. По ΡΡŠΡ‰Π΅ΡΡ‚Π²ΠΎ Ρ‚ΠΎΠ²Π° Π΅ ΠΎΡ‚Π΄Π΅Π»Π΅Π½ ThreadPool. РСшава ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, Ρ‡Π΅ Π² .NET ThreadPool Π΅ статичСн клас, Π΅Π΄ΠΈΠ½ Π·Π° всички прилоТСния, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΏΡ€Π΅Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ ΠΈΠ»ΠΈ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎΡ‚ΠΎ ΠΌΡƒ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π² Π΅Π΄Π½Π° част Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ странични Π΅Ρ„Π΅ΠΊΡ‚ΠΈ Π² Π΄Ρ€ΡƒΠ³Π°. ОсвСн Ρ‚ΠΎΠ²Π° Π΅ ΠΈΠ·ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ Π΄Π° сС Ρ€Π°Π·Π±Π΅Ρ€Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°Ρ‚Π° Π·Π° Ρ‚Π°ΠΊΠΈΠ²Π° Π΄Π΅Ρ„Π΅ΠΊΡ‚ΠΈ. Π§Π΅. МоТС Π΄Π° ΠΈΠΌΠ° Π½ΡƒΠΆΠ΄Π° ΠΎΡ‚ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ WorkStealingTaskSchedulers Π² части ΠΎΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ThreadPool ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС агрСсивно ΠΈ Π½Π΅ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ΠΈΠΌΠΎ.
  • QueuedTaskScheduler β€” Π²ΠΈ позволява Π΄Π° ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ спорСд ΠΏΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π° Π·Π° ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Π° опашка
  • ThreadPerTaskScheduler β€” създава ΠΎΡ‚Π΄Π΅Π»Π½Π° нишка Π·Π° всяка Π·Π°Π΄Π°Ρ‡Π°, която сС изпълнява Π²ΡŠΡ€Ρ…Ρƒ нСя. МоТС Π΄Π° бъдС ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π·Π° Π·Π°Π΄Π°Ρ‡ΠΈ, Ρ‡ΠΈΠ΅Ρ‚ΠΎ изпълнСниС ΠΎΡ‚Π½Π΅ΠΌΠ° нСпрСдсказуСмо дълго Π²Ρ€Π΅ΠΌΠ΅.

Има Π΄ΠΎΠ±ΡŠΡ€ Π΄Π΅Ρ‚Π°ΠΉΠ» статия относно TaskSchedulers Π² Π±Π»ΠΎΠ³Π° Π½Π° Microsoft.

Π—Π° ΡƒΠ΄ΠΎΠ±Π½ΠΎ отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ Π½Π° всичко, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎ със Π—Π°Π΄Π°Ρ‡ΠΈ, Visual Studio ΠΈΠΌΠ° ΠΏΡ€ΠΎΠ·ΠΎΡ€Π΅Ρ† Π—Π°Π΄Π°Ρ‡ΠΈ. Π’ Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΎΠ·ΠΎΡ€Π΅Ρ† ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ‚Π΅ΠΊΡƒΡ‰ΠΎΡ‚ΠΎ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ Π½Π° Π·Π°Π΄Π°Ρ‡Π°Ρ‚Π° ΠΈ Π΄Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅Ρ‚Π΅ към Ρ‚Π΅ΠΊΡƒΡ‰ΠΎ изпълнявания Ρ€Π΅Π΄ ΠΎΡ‚ ΠΊΠΎΠ΄.

.NET: Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚ΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с многопоточност ΠΈ асинхронност. Част 1

PLinq ΠΈ паралСлният клас

Π’ допълнСниС към Tasks ΠΈ всичко ΠΊΠ°Π·Π°Π½ΠΎ Π·Π° тях, Π² .NET ΠΈΠΌΠ° ΠΎΡ‰Π΅ Π΄Π²Π° интСрСсни инструмСнта: PLinq (Linq2Parallel) ΠΈ класа Parallel. ΠŸΡŠΡ€Π²ΠΈΡΡ‚ ΠΎΠ±Π΅Ρ‰Π°Π²Π° ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ изпълнСниС Π½Π° всички Linq ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π° мноТСство нишки. Броят Π½Π° Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π½Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ WithDegreeOfParalleism. Π—Π° съТалСниС Π½Π°ΠΉ-чСсто PLinq Π² Ρ€Π΅ΠΆΠΈΠΌΠ° си ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ няма Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ информация Π·Π° Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΎΡΡ‚Ρ‚Π° Π½Π° вашия ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ Π½Π° Π΄Π°Π½Π½ΠΈ, Π·Π° Π΄Π° осигури Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π½Π° скоростта, ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π° страна, Ρ†Π΅Π½Π°Ρ‚Π° Π½Π° ΠΎΠΏΠΈΡ‚Π° Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ниска: просто трябва Π΄Π° ΠΈΠ·Π²ΠΈΠΊΠ°Ρ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° AsParallel ΠΏΡ€Π΅Π΄ΠΈ Π²Π΅Ρ€ΠΈΠ³Π°Ρ‚Π° ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π½Π° Linq ΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Ρ‚Π΅ тСстовС Π·Π° СфСктивност. ОсвСн Ρ‚ΠΎΠ²Π° Π΅ възмоТно Π΄Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΠΈΡ‚Π΅ Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½Π° информация към PLinq относно СстСството Π½Π° вашия ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ Π½Π° Π΄Π°Π½Π½ΠΈ, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° Π·Π° дяловС. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ ΠΏΠΎΠ²Π΅Ρ‡Π΅ Ρ‚ΡƒΠΊ ΠΈ Ρ‚ΡƒΠΊ.

Бтатичният клас Parallel прСдоставя ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° итСрация ΠΏΡ€Π΅Π· колСкция Foreach ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ, изпълнСниС Π½Π° For Ρ†ΠΈΠΊΡŠΠ» ΠΈ изпълнСниС Π½Π° мноТСство Π΄Π΅Π»Π΅Π³Π°Ρ‚ΠΈ Π² ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅. Π˜Π·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° нишка Ρ‰Π΅ бъдС спряно, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ изчислСнията Π½Π΅ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡Π°Ρ‚. Броят Π½Π° Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½ Ρ‡Ρ€Π΅Π· ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ParallelOptions ΠΊΠ°Ρ‚ΠΎ послСдСн Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚. ΠœΠΎΠΆΠ΅Ρ‚Π΅ ΡΡŠΡ‰ΠΎ Π΄Π° посочитС TaskScheduler ΠΈ CancellationToken, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΎΠΏΡ†ΠΈΠΈ.

Π”Π°Π½Π½ΠΈ

ΠšΠΎΠ³Π°Ρ‚ΠΎ Π·Π°ΠΏΠΎΡ‡Π½Π°Ρ… Π΄Π° пиша Ρ‚Π°Π·ΠΈ статия въз основа Π½Π° ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΡ‚Π΅ ΠΎΡ‚ моя Π΄ΠΎΠΊΠ»Π°Π΄ ΠΈ информацията, която ΡΡŠΠ±Ρ€Π°Ρ… ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° си слСд Π½Π΅Π³ΠΎ, Π½Π΅ ΠΎΡ‡Π°ΠΊΠ²Π°Ρ…, Ρ‡Π΅ Ρ‰Π΅ ΠΈΠΌΠ° Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΌΠ½ΠΎΠ³ΠΎ. Π‘Π΅Π³Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ тСкстовият Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€, Π² ΠΊΠΎΠΉΡ‚ΠΎ пиша Ρ‚Π°Π·ΠΈ статия, ΠΌΠΈ ΠΊΠ°ΠΆΠ΅ ΡƒΠΊΠΎΡ€ΠΈΡ‚Π΅Π»Π½ΠΎ, Ρ‡Π΅ страница 15 Π΅ ΠΈΠ·Ρ‡Π΅Π·Π½Π°Π»Π°, Ρ‰Π΅ обобщя ΠΌΠ΅ΠΆΠ΄ΠΈΠ½Π½ΠΈΡ‚Π΅ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈ. Π”Ρ€ΡƒΠ³ΠΈ Ρ‚Ρ€ΠΈΠΊΠΎΠ²Π΅, API, Π²ΠΈΠ·ΡƒΠ°Π»Π½ΠΈ инструмСнти ΠΈ ΠΊΠ»ΠΎΠΏΠΊΠΈ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ Ρ€Π°Π·Π³Π»Π΅Π΄Π°Π½ΠΈ Π² слСдващата статия.

Изводи:

  • Врябва Π΄Π° Π·Π½Π°Π΅Ρ‚Π΅ инструмСнтитС Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с нишки, асинхронност ΠΈ ΠΏΠ°Ρ€Π°Π»Π΅Π»ΠΈΠ·ΡŠΠΌ, Π·Π° Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ рСсурситС Π½Π° ΡΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈΡ‚Π΅ ΠΊΠΎΠΌΠΏΡŽΡ‚Ρ€ΠΈ.
  • .NET ΠΈΠΌΠ° ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ инструмСнти Π·Π° Ρ‚Π΅Π·ΠΈ Ρ†Π΅Π»ΠΈ
  • НС всички ΠΎΡ‚ тях сС появиха навСднъТ, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ чСсто ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ наслСдСни, Π½ΠΎ ΠΈΠΌΠ° Π½Π°Ρ‡ΠΈΠ½ΠΈ Π΄Π° ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€Π°Ρ‚Π΅ стари API Π±Π΅Π· ΠΌΠ½ΠΎΠ³ΠΎ усилия.
  • Π Π°Π±ΠΎΡ‚Π°Ρ‚Π° с нишки Π² .NET Π΅ прСдставСна ΠΎΡ‚ класовСтС Thread ΠΈ ThreadPool
  • ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈΡ‚Π΅ Thread.Abort, Thread.Interrupt ΠΈ Win32 API TerminateThread са опасни ΠΈ Π½Π΅ сС ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡Π²Π°Ρ‚ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅. ВмСсто Ρ‚ΠΎΠ²Π° Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° CancellationToken
  • ΠŸΠΎΡ‚ΠΎΠΊΡŠΡ‚ Π΅ Ρ†Π΅Π½Π΅Π½ рСсурс ΠΈ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ. Врябва Π΄Π° сС избягват ситуации, ΠΏΡ€ΠΈ ΠΊΠΎΠΈΡ‚ΠΎ Π½ΠΈΡˆΠΊΠΈΡ‚Π΅ са Π·Π°Π΅Ρ‚ΠΈ Π² ΠΎΡ‡Π°ΠΊΠ²Π°Π½Π΅ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ. Π—Π° Ρ‚ΠΎΠ²Π° Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ класа TaskCompletionSource
  • Най-ΠΌΠΎΡ‰Π½ΠΈΡ‚Π΅ ΠΈ ΡƒΡΡŠΠ²ΡŠΡ€ΡˆΠ΅Π½ΡΡ‚Π²Π°Π½ΠΈ .NET инструмСнти Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с ΠΏΠ°Ρ€Π°Π»Π΅Π»ΠΈΠ·ΡŠΠΌ ΠΈ асинхронност са Tasks.
  • C# async/await ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Ρ‚ концСпцията Π·Π° Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€Π°Ρ‰ΠΎ ΠΈΠ·Ρ‡Π°ΠΊΠ²Π°Π½Π΅
  • ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€Π°Ρ‚Π΅ Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΡˆΠΊΠΈΡ‚Π΅, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ класовС, ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈ ΠΎΡ‚ TaskScheduler
  • Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° ValueTask ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΏΠΎΠ»Π΅Π·Π½Π° Π·Π° ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° Π³ΠΎΡ€Π΅Ρ‰ΠΈ ΠΏΡŠΡ‚ΠΈΡ‰Π° ΠΈ Ρ‚Ρ€Π°Ρ„ΠΈΠΊ Π½Π° ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π°
  • ΠŸΡ€ΠΎΠ·ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π·Π° Π·Π°Π΄Π°Ρ‡ΠΈ ΠΈ нишки Π½Π° Visual Studio прСдоставят ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅Π·Π½Π° информация Π·Π° отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ Π² многонишков ΠΈΠ»ΠΈ асинхронСн ΠΊΠΎΠ΄
  • PLinq Π΅ страхотСн инструмСнт, Π½ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° няма Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ информация Π·Π° вашия ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ Π½Π° Π΄Π°Π½Π½ΠΈ, Π½ΠΎ Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΠΎΠΏΡ€Π°Π²ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° Π·Π° раздСлянС
  • Π—Π° Π΄Π° сС ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈ ...

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€