ΠΡΠ±Π»ΠΈΠΊΡΠ²Π°ΠΌ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ Π½Π° 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 ΡΠ΅ Π²ΡΠ·ΠΏΡΠΈΠ΅ΠΌΠ°Ρ ΠΊΠ°ΡΠΎ ΠΏΡΠ΅ΠΏΠΎΡΡΠΊΠ° ΠΏΡΠΈ ΡΠ°Π·Π΄Π΅Π»ΡΠ½Π΅ΡΠΎ Π½Π° ΠΏΡΠΎΡΠ΅ΡΠΎΡΠ½ΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Π½ΠΈΡΠΊΠΈΡΠ΅.
ΠΠ°ΡΠ°Π»Π΅Π»Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π½Π° Π·Π°Π΄Π°ΡΠΈΡΠ΅
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 β ΡΡΠ·Π΄Π°Π²Π° ΠΎΡΠ΄Π΅Π»Π½Π° Π½ΠΈΡΠΊΠ° Π·Π° Π²ΡΡΠΊΠ° Π·Π°Π΄Π°ΡΠ°, ΠΊΠΎΡΡΠΎ ΡΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° Π²ΡΡΡ Ρ Π½Π΅Ρ. ΠΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π·Π° Π·Π°Π΄Π°ΡΠΈ, ΡΠΈΠ΅ΡΠΎ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΡΠ½Π΅ΠΌΠ° Π½Π΅ΠΏΡΠ΅Π΄ΡΠΊΠ°Π·ΡΠ΅ΠΌΠΎ Π΄ΡΠ»Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅.
ΠΠΌΠ° Π΄ΠΎΠ±ΡΡ Π΄Π΅ΡΠ°ΠΉΠ»
ΠΠ° ΡΠ΄ΠΎΠ±Π½ΠΎ ΠΎΡΡΡΡΠ°Π½ΡΠ²Π°Π½Π΅ Π½Π° Π³ΡΠ΅ΡΠΊΠΈ Π½Π° Π²ΡΠΈΡΠΊΠΎ, ΡΠ²ΡΡΠ·Π°Π½ΠΎ ΡΡΡ ΠΠ°Π΄Π°ΡΠΈ, Visual Studio ΠΈΠΌΠ° ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ ΠΠ°Π΄Π°ΡΠΈ. Π ΡΠΎΠ·ΠΈ ΠΏΡΠΎΠ·ΠΎΡΠ΅Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅ ΡΠ΅ΠΊΡΡΠΎΡΠΎ ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ Π½Π° Π·Π°Π΄Π°ΡΠ°ΡΠ° ΠΈ Π΄Π° ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ΡΠ΅ ΠΊΡΠΌ ΡΠ΅ΠΊΡΡΠΎ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°Π½ΠΈΡ ΡΠ΅Π΄ ΠΎΡ ΠΊΠΎΠ΄.
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