.NET: ื›ืœื™ื ืœืขื‘ื•ื“ื” ืขื ืจื™ื‘ื•ื™ ื”ืฉื—ืœื•ืช ื•ื-ืกื™ื ื›ืจื•ืŸ. ื—ืœืง 1

ืื ื™ ืžืคืจืกื ืืช ื”ืžืืžืจ ื”ืžืงื•ืจื™ ืขืœ Habr, ืฉืชืจื’ื•ืžื• ืคื•ืจืกื ื‘ืชืื’ื™ื“ ืคื•ืกื˜ ื‘ื‘ืœื•ื’.

ื”ืฆื•ืจืš ืœืขืฉื•ืช ืžืฉื”ื• ื‘ืื•ืคืŸ ืืกื™ื ื›ืจื•ื ื™, ืžื‘ืœื™ ืœื—ื›ื•ืช ืœืชื•ืฆืื” ื›ืืŸ ื•ืขื›ืฉื™ื•, ืื• ืœื—ืœืง ืขื‘ื•ื“ื” ื’ื“ื•ืœื” ื‘ื™ืŸ ืžืกืคืจ ื™ื—ื™ื“ื•ืช ื”ืžื‘ืฆืขื•ืช ืื•ืชื•, ื”ื™ื” ืงื™ื™ื ืœืคื ื™ ื”ื•ืคืขืช ื”ืžื—ืฉื‘ื™ื. ืขื ื”ื•ืคืขืชื, ื”ืฆื•ืจืš ื”ื–ื” ื”ืคืš ืœืžื•ื—ืฉื™ ืžืื•ื“. ื›ืขืช, ื‘ืฉื ืช 2019, ืื ื™ ืžืงืœื™ื“ ืืช ื”ืžืืžืจ ื”ื–ื” ืขืœ ืžื—ืฉื‘ ื ื™ื™ื“ ืขื ืžืขื‘ื“ Intel Core 8 ืœื™ื‘ื•ืช, ืขืœื™ื• ืคื•ืขืœื™ื ื™ื•ืชืจ ืžืžืื” ืชื”ืœื™ื›ื™ื ื‘ืžืงื‘ื™ืœ, ื•ืขื•ื“ ื™ื•ืชืจ ืฉืจืฉื•ืจื™ื. ื‘ืงืจื‘ืช ืžืงื•ื, ื™ืฉ ื˜ืœืคื•ืŸ ืžืขื˜ ืขืœื•ื‘, ืฉื ืงื ื” ืœืคื ื™ ื›ืžื” ืฉื ื™ื, ื™ืฉ ืœื• ืžืขื‘ื“ 8 ืœื™ื‘ื•ืช ืขืœ ื”ืกื™ืคื•ืŸ. ืžืฉืื‘ื™ื ื ื•ืฉืื™ื™ื ืžืœืื™ื ื‘ืžืืžืจื™ื ื•ื‘ืกืจื˜ื•ื ื™ื ืฉื‘ื”ื ื”ืžื—ื‘ืจื™ื ืฉืœื”ื ืžืขืจื™ืฆื™ื ืืช ืกืžืืจื˜ืคื•ื ื™ื ื”ื“ื’ืœ ืฉืœ ื”ืฉื ื” ื”ื›ื•ืœืœื™ื ืžืขื‘ื“ื™ื ื‘ืขืœื™ 16 ืœื™ื‘ื•ืช. MS Azure ืžืกืคืงืช ืžื›ื•ื ื” ื•ื™ืจื˜ื•ืืœื™ืช ืขื ืžืขื‘ื“ 20 ืœื™ื‘ื•ืช ื•-128 TB RAM ื‘ืคื—ื•ืช ืž-$2 ืœืฉืขื”. ืœืžืจื‘ื” ื”ืฆืขืจ, ืื™ ืืคืฉืจ ืœื—ืœืฅ ืืช ื”ืžืงืกื™ืžื•ื ื•ืœืจืชื•ื ืืช ื”ื›ื•ื— ื”ื–ื” ืžื‘ืœื™ ืœื”ื™ื•ืช ืžืกื•ื’ืœ ืœื ื”ืœ ืืช ื”ืื™ื ื˜ืจืืงืฆื™ื” ืฉืœ ื—ื•ื˜ื™ื.

ื˜ืจืžื™ื ื•ืœื•ื’ื™ื”

ืชื”ืœื™ืš - ืื•ื‘ื™ื™ืงื˜ ืžืขืจื›ืช ื”ื”ืคืขืœื”, ืžืจื—ื‘ ื›ืชื•ื‘ื•ืช ืžื‘ื•ื“ื“, ืžื›ื™ืœ ืฉืจืฉื•ืจื™ื.
ืคึผึฐืชึดื™ืœ - ืื•ื‘ื™ื™ืงื˜ OS, ื™ื—ื™ื“ืช ื”ื‘ื™ืฆื•ืข ื”ืงื˜ื ื” ื‘ื™ื•ืชืจ, ื—ืœืง ืžืชื”ืœื™ืš, ื—ื•ื˜ื™ื ื—ื•ืœืงื™ื ื‘ื™ื ื™ื”ื ื–ื™ื›ืจื•ืŸ ื•ืžืฉืื‘ื™ื ืื—ืจื™ื ื‘ืชื•ืš ืชื”ืœื™ืš.
ืจื™ื‘ื•ื™ ืžืฉื™ืžื•ืช - ืžืืคื™ื™ืŸ ืžืขืจื›ืช ื”ื”ืคืขืœื”, ื”ื™ื›ื•ืœืช ืœื”ืคืขื™ืœ ืžืกืคืจ ืชื”ืœื™ื›ื™ื ื‘ื• ื–ืžื ื™ืช
ืจื‘ ืœื™ื‘ื•ืช - ืชื›ื•ื ื” ืฉืœ ื”ืžืขื‘ื“, ื”ื™ื›ื•ืœืช ืœื”ืฉืชืžืฉ ื‘ืžืกืคืจ ืœื™ื‘ื•ืช ืœืขื™ื‘ื•ื“ ื ืชื•ื ื™ื
ืจื™ื‘ื•ื™ ืขื™ื‘ื•ื“ื™ื - ืชื›ื•ื ื” ืฉืœ ืžื—ืฉื‘, ื”ื™ื›ื•ืœืช ืœืขื‘ื•ื“ ื‘ื• ื–ืžื ื™ืช ืขื ืžืกืคืจ ืžืขื‘ื“ื™ื ืคื™ื–ื™ืช
ืจื™ื‘ื•ื™ ื”ืฉืจืฉื•ืจื™ื - ืชื›ื•ื ื” ืฉืœ ืชื”ืœื™ืš, ื”ื™ื›ื•ืœืช ืœื”ืคื™ืฅ ืขื™ื‘ื•ื“ ื ืชื•ื ื™ื ื‘ื™ืŸ ืžืกืคืจ ืฉืจืฉื•ืจื™ื.
ืžึทืงื‘ึผึดื™ืœื•ึผืช - ื‘ื™ืฆื•ืข ืžืกืคืจ ืคืขื•ืœื•ืช ืคื™ื–ื™ืช ื‘ื• ื–ืžื ื™ืช ืœื™ื—ื™ื“ืช ื–ืžืŸ
ืืกื™ื ื›ืจื•ื ื™ื” - ื‘ื™ืฆื•ืข ืคืขื•ืœื” ืœืœื ื”ืžืชื ื” ืœื”ืฉืœืžืช ืขื™ื‘ื•ื“ ื–ื”; ื ื™ืชืŸ ืœืขื‘ื“ ืืช ืชื•ืฆืืช ื”ื‘ื™ืฆื•ืข ืžืื•ื—ืจ ื™ื•ืชืจ.

ืžื˜ืืคื•ืจื”

ืœื ื›ืœ ื”ื”ื’ื“ืจื•ืช ื˜ื•ื‘ื•ืช ื•ื—ืœืงืŸ ื–ืงื•ืงื•ืช ืœื”ืกื‘ืจ ื ื•ืกืฃ, ืื– ืื•ืกื™ืฃ ืžื˜ืืคื•ืจื” ืขืœ ื‘ื™ืฉื•ืœ ืืจื•ื—ืช ื‘ื•ืงืจ ืœืžื™ื ื•ื— ืฉื”ื•ืฆื’ ืจืฉืžื™ืช. ื‘ื™ืฉื•ืœ ืืจื•ื—ืช ื‘ื•ืงืจ ื‘ืžื˜ืืคื•ืจื” ื–ื• ื”ื•ื ืชื”ืœื™ืš.

ื‘ื–ืžืŸ ื”ื›ื ืช ืืจื•ื—ืช ื”ื‘ื•ืงืจ ื‘ื‘ื•ืงืจ ืื ื™ (CPU) ืื ื™ ื‘ื ืœืžื˜ื‘ื— (ืžื—ืฉื‘). ื™ืฉ ืœื™ 2 ื™ื“ื™ื™ื (ืœื™ื‘ื•ืช). ื™ืฉื ื ืžืกืคืจ ืžื›ืฉื™ืจื™ื ื‘ืžื˜ื‘ื— (IO): ืชื ื•ืจ, ืงื•ืžืงื•ื, ื˜ื•ืกื˜ืจ, ืžืงืจืจ. ืื ื™ ืžื“ืœื™ืง ืืช ื”ื’ื–, ืฉื ืขืœื™ื• ืžื—ื‘ืช ื•ื™ื•ืฆืง ืœืชื•ื›ื• ืฉืžืŸ ื‘ืœื™ ืœื—ื›ื•ืช ืฉื™ืชื—ืžื (ื‘ืื•ืคืŸ ืืกื™ื ื›ืจื•ื ื™, Non-Blocking-IO-Wait), ืื ื™ ืžื•ืฆื™ื ืืช ื”ื‘ื™ืฆื™ื ืžื”ืžืงืจืจ ื•ืฉื•ื‘ืจ ืื•ืชืŸ ืœืฆืœื—ืช, ื•ืื– ื˜ื•ืจืฃ ืื•ืชืŸ ื‘ื™ื“ ืื—ืช (ืฉืจืฉื•ืจ ืžืก' 1), ื•ื”ืฉื ื™ื™ื” (ืฉืจืฉื•ืจ ืžืก' 2) ืžื—ื–ื™ืง ืืช ื”ืฆืœื—ืช (ืžืฉืื‘ ืžืฉื•ืชืฃ). ืขื›ืฉื™ื• ืื ื™ ืจื•ืฆื” ืœื”ื“ืœื™ืง ืืช ื”ืงื•ืžืงื•ื, ืื‘ืœ ืื™ืŸ ืœื™ ืžืกืคื™ืง ื™ื“ื™ื™ื (ืฉืจืฉื•ืจ ื”ืจืขื‘ื”) ื‘ื–ืžืŸ ื”ื–ื” ื”ืžื—ื‘ืช ืžืชื—ืžืžืช (ืžืขื‘ื“ ืืช ื”ืชื•ืฆืื”) ืืœื™ื” ืื ื™ ื™ื•ืฆืง ืืช ืžื” ืฉื”ืงืฆืคืชื™. ืื ื™ ืžื•ืฉื™ื˜ ืืช ื™ื“ื• ืืœ ื”ืงื•ืžืงื•ื ื•ืžื“ืœื™ืง ืื•ืชื• ื•ืžืชื‘ื•ื ืŸ ื‘ื˜ื™ืคืฉื•ืช ื‘ืžื™ื ืจื•ืชื—ื™ื ื‘ื• (ื—ืกื™ืžื”-IO-ื”ืžืชื ื”), ืœืžืจื•ืช ืฉื‘ื–ืžืŸ ื”ื–ื” ื”ื•ื ื™ื›ื•ืœ ื”ื™ื” ืœืฉื˜ื•ืฃ ืืช ื”ืฆืœื—ืช ืฉื‘ื” ื”ืงืฆื™ืฃ ืืช ื”ื—ื‘ื™ืชื”.

ื‘ื™ืฉืœืชื™ ื—ื‘ื™ืชื” ื‘ืฉืชื™ ื™ื“ื™ื™ื ื‘ืœื‘ื“, ื•ืื™ืŸ ืœื™ ื™ื•ืชืจ, ืื‘ืœ ื‘ืžืงื‘ื™ืœ, ื‘ืจื’ืข ื”ื”ืงืฆืคื” ืฉืœ ื”ื—ื‘ื™ืชื” ื‘ื•ืฆืขื• 2 ืคืขื•ืœื•ืช ื‘ื‘ืช ืื—ืช: ื”ืงืฆืคืช ื”ื—ื‘ื™ืชื”, ื”ื—ื–ืงืช ื”ืฆืœื—ืช, ื—ื™ืžื•ื ื”ืžื—ื‘ืช. ื”-CPU ื”ื•ื ื”ื—ืœืง ื”ืžื”ื™ืจ ื‘ื™ื•ืชืจ ื‘ืžื—ืฉื‘, IO ื”ื•ื ืžื” ืฉืœืจื•ื‘ ื”ื›ืœ ืžืื˜, ื•ืœื›ืŸ ืœืขืชื™ื ืงืจื•ื‘ื•ืช ืคืชืจื•ืŸ ื™ืขื™ืœ ื”ื•ื ืœื”ืขืกื™ืง ืืช ื”-CPU ื‘ืžืฉื”ื• ืชื•ืš ื›ื“ื™ ืงื‘ืœืช ื ืชื•ื ื™ื ืž-IO.

ื”ืžืฉืš ื”ืžื˜ืืคื•ืจื”:

  • ืื ื‘ืชื”ืœื™ืš ื”ื›ื ืช ื—ื‘ื™ืชื”, ื”ื™ื™ืชื™ ืžื ืกื” ื’ื ืœื”ื—ืœื™ืฃ ื‘ื’ื“ื™ื, ื–ื• ืชื”ื™ื” ื“ื•ื’ืžื” ืœืจื™ื‘ื•ื™ ืžืฉื™ืžื•ืช. ื ื™ื•ืื ืก ื—ืฉื•ื‘: ืžื—ืฉื‘ื™ื ื˜ื•ื‘ื™ื ื‘ื–ื” ื”ืจื‘ื” ื™ื•ืชืจ ืžืื ืฉื™ื.
  • ืžื˜ื‘ื— ืขื ืžืกืคืจ ืฉืคื™ื, ืœืžืฉืœ ื‘ืžืกืขื“ื” - ืžื—ืฉื‘ ืจื‘ ืœื™ื‘ื•ืช.
  • ืžืกืขื“ื•ืช ืจื‘ื•ืช ื‘ืžืชื—ื ืื•ื›ืœ ื‘ืžืจื›ื– ืงื ื™ื•ืช - ื“ืื˜ื” ืกื ื˜ืจ

ื›ืœื™ NET

NET ื˜ื•ื‘ื” ื‘ืขื‘ื•ื“ื” ืขื ืฉืจืฉื•ืจื™ื, ื›ืžื• ืขื ื”ืจื‘ื” ื“ื‘ืจื™ื ืื—ืจื™ื. ืขื ื›ืœ ื’ืจืกื” ื—ื“ืฉื”, ื”ื™ื ืžืฆื™ื’ื” ื™ื•ืชืจ ื•ื™ื•ืชืจ ื›ืœื™ื ื—ื“ืฉื™ื ืœืขื‘ื•ื“ื” ืื™ืชื, ืฉื›ื‘ื•ืช ื—ื“ืฉื•ืช ืฉืœ ื”ืคืฉื˜ื” ืขืœ ื—ื•ื˜ื™ ืžืขืจื›ืช ื”ื”ืคืขืœื”. ื›ืืฉืจ ืขื•ื‘ื“ื™ื ืขื ื‘ื ื™ื™ืช ื”ืคืฉื˜ื•ืช, ืžืคืชื—ื™ ืžืกื’ืจืช ืžืฉืชืžืฉื™ื ื‘ื’ื™ืฉื” ืฉืžื•ืชื™ืจื” ืืช ื”ื”ื–ื“ืžื ื•ืช, ื‘ืขืช ืฉื™ืžื•ืฉ ื‘ื”ืคืฉื˜ื” ื‘ืจืžื” ื’ื‘ื•ื”ื”, ืœืจื“ืช ืจืžื” ืื—ืช ืื• ื™ื•ืชืจ ืœืžื˜ื”. ืœืจื•ื‘ ื–ื” ืœื ื”ื›ืจื—ื™, ืœืžืขืฉื” ื–ื” ืคื•ืชื— ืืช ื”ื“ืœืช ืœื™ืจื•ืช ืœืขืฆืžืš ื‘ืจื’ืœ ืขื ืจื•ื‘ื” ืฆื™ื“, ืื‘ืœ ืœืคืขืžื™ื, ื‘ืžืงืจื™ื ื ื“ื™ืจื™ื, ื–ื• ืขืฉื•ื™ื” ืœื”ื™ื•ืช ื”ื“ืจืš ื”ื™ื—ื™ื“ื” ืœืคืชื•ืจ ื‘ืขื™ื” ืฉืœื ื ืคืชืจืช ื‘ืจืžืช ื”ื”ืคืฉื˜ื” ื”ื ื•ื›ื—ื™ืช .

ื‘ื›ืœื™ื, ืื ื™ ืžืชื›ื•ื•ืŸ ื”ืŸ ืœืžืžืฉืงื™ ืชื›ื ื•ืช ื™ื™ืฉื•ืžื™ื (API) ื”ืžืกื•ืคืงื™ื ืขืœ ื™ื“ื™ ื”ืžืกื’ืจืช ื•ื”ืŸ ืœื—ื‘ื™ืœื•ืช ืฉืœ ืฆื“ ืฉืœื™ืฉื™, ื›ืžื• ื’ื ืœืคืชืจื•ื ื•ืช ืชื•ื›ื ื” ืฉืœืžื™ื ื”ืžืคืฉื˜ื™ื ืืช ื”ื—ื™ืคื•ืฉ ืื—ืจ ื›ืœ ื‘ืขื™ื” ื”ืงืฉื•ืจื” ืœืงื•ื“ ืžืจื•ื‘ื” ื”ืœื™ื›ื™.

ืคื•ืชื— ืฉืจืฉื•ืจ

ื”ืžื—ืœืงื” Thread ื”ื™ื ื”ืžื—ืœืงื” ื”ื‘ืกื™ืกื™ืช ื‘ื™ื•ืชืจ ื‘-.NET ืœืขื‘ื•ื“ื” ืขื ืฉืจืฉื•ืจื™ื. ื”ื‘ื ืื™ ืžืงื‘ืœ ืื—ื“ ืžืฉื ื™ ื ืฆื™ื’ื™ื:

  • ThreadStart - ืื™ืŸ ืคืจืžื˜ืจื™ื
  • ParametrizedThreadStart - ืขื ืคืจืžื˜ืจ ืื—ื“ ืžืกื•ื’ ืื•ื‘ื™ื™ืงื˜.

ื”ื ืฆื™ื’ ื™ื‘ื•ืฆืข ื‘ืฉืจืฉื•ืจ ื”ื—ื“ืฉ ืฉื ื•ืฆืจ ืœืื—ืจ ืงืจื™ืื” ืœืžืชื•ื“ื” Start.ืื ื ืฆื™ื’ ืžืกื•ื’ ParametrizedThreadStart ื”ื•ืขื‘ืจ ืœื‘ื ืื™, ืื– ื™ืฉ ืœื”ืขื‘ื™ืจ ืื•ื‘ื™ื™ืงื˜ ืœืžืชื•ื“ื” Start. ืžื ื’ื ื•ืŸ ื–ื” ื ื—ื•ืฅ ื›ื“ื™ ืœื”ืขื‘ื™ืจ ื›ืœ ืžื™ื“ืข ืžืงื•ืžื™ ืœื–ืจื. ืจืื•ื™ ืœืฆื™ื™ืŸ ืฉื™ืฆื™ืจืช ืฉืจืฉื•ืจ ื”ื™ื ืคืขื•ืœื” ื™ืงืจื”, ื•ื”ืฉืจืฉื•ืจ ืขืฆืžื• ื”ื•ื ืื•ื‘ื™ื™ืงื˜ ื›ื‘ื“, ืœืคื—ื•ืช ื‘ื’ืœืœ ืฉื”ื•ื ืžืงืฆื” 1MB ืฉืœ ื–ื™ื›ืจื•ืŸ ืขืœ ื”ืžื—ืกื ื™ืช ื•ื“ื•ืจืฉ ืื™ื ื˜ืจืืงืฆื™ื” ืขื OS API.

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

ืžื—ืœืงืช ThreadPool ืžื™ื™ืฆื’ืช ืืช ื”ืจืขื™ื•ืŸ ืฉืœ ื‘ืจื™ื›ื”. ื‘-.NET, ืžืื’ืจ ื”ืฉืจืฉื•ืจื™ื ื”ื•ื ื—ืชื™ื›ืช ื”ื ื“ืกื”, ื•ื”ืžืคืชื—ื™ื ื‘ืžื™ืงืจื•ืกื•ืคื˜ ื”ืฉืงื™ืขื• ืžืืžืฆื™ื ืจื‘ื™ื ื›ื“ื™ ืœื•ื•ื“ื ืฉื”ื•ื ืคื•ืขืœ ื‘ืฆื•ืจื” ืžื™ื˜ื‘ื™ืช ื‘ืžื’ื•ื•ืŸ ืจื—ื‘ ืฉืœ ืชืจื—ื™ืฉื™ื.

ืžื•ืฉื’ ื›ืœืœื™:

ืžืจื’ืข ื”ืคืขืœืช ื”ืืคืœื™ืงืฆื™ื”, ื”ื™ื ื™ื•ืฆืจืช ืžืกืคืจ ืฉืจืฉื•ืจื™ื ื‘ืจืงืข ื‘ืจืงืข ื•ืžืกืคืงืช ืืช ื”ื™ื›ื•ืœืช ืœืงื—ืช ืื•ืชื ืœืฉื™ืžื•ืฉ. ืื ืžืฉืชืžืฉื™ื ื‘ื—ื•ื˜ื™ื ืชื›ื•ืคื™ื ื•ื‘ืžืกืคืจื™ื ื’ื“ื•ืœื™ื, ื”ืžืื’ืจ ืžืชืจื—ื‘ ื›ื“ื™ ืœืขื ื•ืช ืขืœ ื”ืฆืจื›ื™ื ืฉืœ ื”ืžืชืงืฉืจ. ื›ืืฉืจ ืื™ืŸ ืฉืจืฉื•ืจื™ื ืคื ื•ื™ื™ื ื‘ื‘ืจื™ื›ื” ื‘ื–ืžืŸ ื”ื ื›ื•ืŸ, ื”ื•ื ื™ื—ื›ื” ืขื“ ืฉืื—ื“ ื”ื—ื•ื˜ื™ื ื™ื—ื–ื•ืจ, ืื• ื™ืฆื•ืจ ืื—ื“ ื—ื“ืฉ. ืžื›ืืŸ ื ื•ื‘ืข ืฉืžืื’ืจ ื”ืฉืจืฉื•ืจื™ื ืžืฆื•ื™ืŸ ืœื›ืžื” ืคืขื•ืœื•ืช ืงืฆืจื•ืช ื˜ื•ื•ื— ื•ืื™ื ื• ืžืชืื™ื ืœืคืขื•ืœื•ืช ื”ืคื•ืขืœื•ืช ื›ืฉื™ืจื•ืชื™ื ืœืื•ืจืš ื›ืœ ืคืขื•ืœืช ื”ืืคืœื™ืงืฆื™ื”.

ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘ืฉืจืฉื•ืจ ืžื”ืžืื’ืจ, ืงื™ื™ืžืช ืฉื™ื˜ืช 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, ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืืช ื”ืขื“ื™ืคื•ืช ืฉืœ thread, ืืฉืจ ื”-OC ื•ื”-CLR ื™ืชืคืกื• ื›ื”ืžืœืฆื” ื‘ืขืช ื—ืœื•ืงืช ื–ืžืŸ ื”ืžืขื‘ื“ ื‘ื™ืŸ ืฉืจืฉื•ืจื™ื.

.NET: ื›ืœื™ื ืœืขื‘ื•ื“ื” ืขื ืจื™ื‘ื•ื™ ื”ืฉื—ืœื•ืช ื•ื-ืกื™ื ื›ืจื•ืŸ. ื—ืœืง 1

ืกืคืจื™ื™ืช ืžืงื‘ื™ืœื•ืช ืžืฉื™ืžื•ืช

ืกืคืจื™ื™ืช ืžืฉื™ืžื•ืช ืžืงื‘ื™ืœื” (TPL) ื”ื•ืฆื’ื” ื‘-.NET 4.0. ืขื›ืฉื™ื• ื–ื” ื”ืกื˜ื ื“ืจื˜ ื•ื”ื›ืœื™ ื”ืขื™ืงืจื™ ืœืขื‘ื•ื“ื” ืขื ืืกื™ื ื›ืจื•ื ื™ื”. ื›ืœ ืงื•ื“ ื”ืžืฉืชืžืฉ ื‘ื’ื™ืฉื” ื™ืฉื ื” ื™ื•ืชืจ ื ื—ืฉื‘ ืœืžื•ืจืฉืช. ื”ื™ื—ื™ื“ื” ื”ื‘ืกื™ืกื™ืช ืฉืœ TPL ื”ื™ื ืžื—ืœืงื” Task ืžืžืจื—ื‘ ื”ืฉืžื•ืช System.Threading.Tasks. ืžืฉื™ืžื” ื”ื™ื ื”ืคืฉื˜ื” ืขืœ ื—ื•ื˜. ืขื ื”ื’ืจืกื” ื”ื—ื“ืฉื” ืฉืœ ืฉืคืช C#, ืงื™ื‘ืœื ื• ื“ืจืš ืืœื’ื ื˜ื™ืช ืœืขื‘ื•ื“ ืขื Tasks - ืื•ืคืจื˜ื•ืจื™ื ืืกื™ื ื›ืจื•ื ื™ื™ื/ืžืžืชื™ื ื™ื. ื”ืžื•ืฉื’ื™ื ื”ืœืœื• ืืคืฉืจื• ืœื›ืชื•ื‘ ืงื•ื“ ืืกื™ื ื›ืจื•ื ื™ ื›ืื™ืœื• ื”ื•ื ืคืฉื•ื˜ ื•ืกื™ื ื›ืจื•ื ื™, ื–ื” ืืคืฉืจ ืืคื™ืœื• ืœืื ืฉื™ื ืขื ื”ื‘ื ื” ืžื•ืขื˜ื” ืฉืœ โ€‹โ€‹ืคืขื•ืœืชื ื”ืคื ื™ืžื™ืช ืฉืœ ืฉืจืฉื•ืจื™ื ืœื›ืชื•ื‘ ืืคืœื™ืงืฆื™ื•ืช ืฉืžืฉืชืžืฉื•ืช ื‘ื”ื, ืืคืœื™ืงืฆื™ื•ืช ืฉืœื ืงื•ืคืื•ืช ื‘ืขืช ื‘ื™ืฆื•ืข ืคืขื•ืœื•ืช ืืจื•ื›ื•ืช. ื”ืฉื™ืžื•ืฉ ื‘-async/wait ื”ื•ื ื ื•ืฉื ืœืžืืžืจ ืื—ื“ ืื• ืืคื™ืœื• ืœื›ืžื” ืžืืžืจื™ื, ืื‘ืœ ืื ืกื” ืœื”ื‘ื™ืŸ ืืช ืขื™ืงืจื• ื‘ื›ืžื” ืžืฉืคื˜ื™ื:

  • async ื”ื•ื ืžืฉื ื” ืฉืœ ืฉื™ื˜ื” ื”ืžื—ื–ื™ืจื” Task ืื• void
  • and await ื”ื•ื ืžืคืขื™ืœ ืœื ื—ื•ืกื ืžืฉื™ืžื” ืžื—ื›ื”.

ืฉื•ื‘: ืžืคืขื™ืœ ื”ื”ืžืชื ื”, ื‘ืžืงืจื” ื”ื›ืœืœื™ (ื™ืฉ ื—ืจื™ื’ื™ื), ื™ืฉื—ืจืจ ืืช ืฉืจืฉื•ืจ ื”ื‘ื™ืฆื•ืข ื”ื ื•ื›ื—ื™, ื•ื›ืืฉืจ ื”ืžืฉื™ืžื” ืชืกื™ื™ื ืืช ื‘ื™ืฆื•ืขื”, ื•ืืช ื”ืฉืจืฉื•ืจ (ืœืžืขืฉื”, ื ื›ื•ืŸ ื™ื•ืชืจ ืœื•ืžืจ ืืช ื”ื”ืงืฉืจ , ืืš ืขืœ ื›ืš ื‘ื”ืžืฉืš) ื™ืžืฉื™ืš ื‘ื‘ื™ืฆื•ืข ื”ืฉื™ื˜ื”. ื‘ืชื•ืš NET, ืžื ื’ื ื•ืŸ ื–ื” ืžื™ื•ืฉื ื‘ืื•ืชื• ืื•ืคืŸ ื›ืžื• ื”ื—ื–ืจืช ืชืฉื•ืื”, ื›ืืฉืจ ื”ืฉื™ื˜ื” ื”ื›ืชื•ื‘ื” ื”ื•ืคื›ืช ืœืžื—ืœืงื” ืฉืœืžื”, ืฉื”ื™ื ืžื›ื•ื ืช ืžืฆื‘ื™ื ื•ื ื™ืชื ืช ืœื‘ื™ืฆื•ืข ื‘ื—ืœืงื™ื ื ืคืจื“ื™ื ื‘ื”ืชืื ืœืžืฆื‘ื™ื ืืœื•. ื›ืœ ืžื™ ืฉืžืขื•ื ื™ื™ืŸ ื™ื›ื•ืœ ืœื›ืชื•ื‘ ื›ืœ ืงื•ื“ ืคืฉื•ื˜ ื‘ืืžืฆืขื•ืช asynั/await, ืงื•ืžืคื™ืœืฆื™ื” ื•ื”ืฆื’ื” ืฉืœ ื”ืžื›ืœื•ืœ ื‘ืืžืฆืขื•ืช JetBrains dotPeek ืขื ืงื•ื“ ืžื”ื“ืจ ืžื•ืคืขืœ.

ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ืืคืฉืจื•ื™ื•ืช ืœื”ืคืขืœื” ื•ืฉื™ืžื•ืฉ ื‘-Task. ื‘ื“ื•ื’ืžื” ืฉืœ ื”ืงื•ื“ ืฉืœื”ืœืŸ, ืื ื• ื™ื•ืฆืจื™ื ืžืฉื™ืžื” ื—ื“ืฉื” ืฉืœื ืขื•ืฉื” ืฉื•ื ื“ื‘ืจ ืžื•ืขื™ืœ (ื—ื•ื˜. ืฉื™ื ื” (10000)), ืื‘ืœ ื‘ื—ื™ื™ื ื”ืืžื™ืชื™ื™ื ื–ื• ืืžื•ืจื” ืœื”ื™ื•ืช ืขื‘ื•ื“ื” ืžื•ืจื›ื‘ืช ืขืชื™ืจืช ืžืขื‘ื“.

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. ืื ืื™ืŸ ื‘ื“ื™ืงื•ืช, ืื–ื™ ืฉื™ื˜ืช ื”ื‘ื™ื˜ื•ืœ ื”ื ืงืจืืช ืœืื•ื‘ื™ื™ืงื˜ CancellationTokenSource ืชื•ื›ืœ ืœืขืฆื•ืจ ืืช ื‘ื™ืฆื•ืข ื”ืžืฉื™ืžื” ืจืง ืœืคื ื™ ืฉื”ื™ื ืžืชื—ื™ืœื”.

ื”ืคืจืžื˜ืจ ื”ืื—ืจื•ืŸ ื”ื•ื ืื•ื‘ื™ื™ืงื˜ ืžืชื–ืžืŸ ืžืกื•ื’ TaskScheduler. ืžื—ืœืงื” ื–ื• ื•ืฆืืฆืื™ื” ื ื•ืขื“ื• ืœืฉืœื•ื˜ ื‘ืืกื˜ืจื˜ื’ื™ื•ืช ืœื”ืคืฆืช ืžืฉื™ืžื•ืช ืขืœ ืคื ื™ ืฉืจืฉื•ืจื™ื; ื›ื‘ืจื™ืจืช ืžื—ื“ืœ, ื”ืžืฉื™ืžื” ืชืชื‘ืฆืข ืขืœ ืฉืจืฉื•ืจ ืืงืจืื™ ืžื”ืžืื’ืจ.

ื”ืื•ืคืจื˜ื•ืจ await ืžื•ื—ืœ ืขืœ ื”ืžืฉื™ืžื” ืฉื ื•ืฆืจื”, ื›ืœื•ืžืจ ื”ืงื•ื“ ืฉื ื›ืชื‘ ืื—ืจื™ื•, ืื ื™ืฉ ื›ื–ื”, ื™ืชื‘ืฆืข ื‘ืื•ืชื• ื”ืงืฉืจ (ืœืขื™ืชื™ื ืงืจื•ื‘ื•ืช ื–ื” ืื•ืžืจ ื‘ืื•ืชื• ืฉืจืฉื•ืจ) ื›ืžื• ื”ืงื•ื“ ืฉืœืคื ื™ await.

ื”ืฉื™ื˜ื” ืžืกื•ืžื ืช ื›ื—ืกืจืช ืกื™ื ื›ืจื•ืŸ, ืžื” ืฉืื•ืžืจ ืฉื”ื™ื ื™ื›ื•ืœื” ืœื”ืฉืชืžืฉ ื‘ืื•ืคืจื˜ื•ืจ await, ืืš ื”ืงื•ื“ ื”ืžืชืงืฉืจ ืœื ื™ื•ื›ืœ ืœื—ื›ื•ืช ืœื‘ื™ืฆื•ืข. ืื ื™ืฉ ืฆื•ืจืš ื‘ืชื›ื•ื ื” ื›ื–ื•, ื”ืฉื™ื˜ื” ื—ื™ื™ื‘ืช ืœื”ื—ื–ื™ืจ ืืช ื”ืžืฉื™ืžื”. ืฉื™ื˜ื•ืช ืฉืกื•ืžื ื• ื›ื‘ื˜ืœื•ืช ืืกื™ื ื›ืจื•ืŸ ื”ืŸ ื ืคื•ืฆื•ืช ืœืžื“ื™: ื›ื›ืœืœ, ืืœื• ื”ื ืžื˜ืคืœื™ ืื™ืจื•ืขื™ื ืื• ืฉื™ื˜ื•ืช ืื—ืจื•ืช ืฉืขื•ื‘ื“ื•ืช ืขืœ ืขื™ืงืจื•ืŸ ื”ืืฉ ื•ืฉื›ื—. ืื ืืชื” ืฆืจื™ืš ืœื ืจืง ืœืชืช ืืช ื”ื”ื–ื“ืžื ื•ืช ืœื—ื›ื•ืช ืขื“ ืกื•ืฃ ื”ื‘ื™ืฆื•ืข, ืืœื ื’ื ืœื”ื—ื–ื™ืจ ืืช ื”ืชื•ืฆืื”, ืื– ืืชื” ืฆืจื™ืš ืœื”ืฉืชืžืฉ ื‘ืžืฉื™ืžื”.

ื‘ืžืฉื™ืžื” ืฉืฉื™ื˜ืช 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, ืื– ื ืงื‘ืœ ืžื‘ื•ื™ ืกืชื•ื: ืฉืจืฉื•ืจ ื”ืงื•ืจื ืžืžืชื™ืŸ ื‘ื–ืžืŸ ืฉื”ืชื•ืฆืื” ืฉืœ ื”ืฉื™ื˜ื” ื”ืืกื™ื ื›ืจื•ื ื™ืช ืžื—ื•ืฉื‘ืช, ื”ืฉื™ื˜ื” ื”ื-ืกื™ื ื›ืจื•ื ื™ืช ืžื ืกื” ืœืฉื•ื•ื ืœื”ืžืฉื™ืš ืืช ื‘ื™ืฆื•ืขื” ื‘ืฉืจืฉื•ืจ ื”ืงื•ืจื.

ื—ื™ืกืจื•ืŸ ื ื•ืกืฃ ืฉืœ ื’ื™ืฉื” ื–ื• ื”ื•ื ื˜ื™ืคื•ืœ ื‘ืฉื’ื™ืื•ืช ืžืกื•ื‘ืš. ื”ืขื•ื‘ื“ื” ื”ื™ื ืฉืงืœ ืžืื•ื“ ืœื˜ืคืœ ื‘ืฉื’ื™ืื•ืช ื‘ืงื•ื“ ืืกื™ื ื›ืจื•ื ื™ ื‘ืขืช ืฉื™ืžื•ืฉ ื‘-async/wait - ื”ืŸ ืžืชื ื”ื’ื•ืช ืื•ืชื• ื“ื‘ืจ ื›ืื™ืœื• ื”ืงื•ื“ ื”ื™ื” ืกื™ื ื›ืจื•ื ื™. ื‘ืขื•ื“ ืฉืื ื ื—ื™ืœ ื’ื™ืจื•ืฉ ืฉื“ื™ื ืกื™ื ื›ืจื•ื ื™ ืขืœ ืžืฉื™ืžื”, ื”ื—ืจื™ื’ ื”ืžืงื•ืจื™ ื”ื•ืคืš ืœ-AggregateException, ื›ืœื•ืžืจ. ื›ื“ื™ ืœื”ืชืžื•ื“ื“ ืขื ื”ื—ืจื™ื’ื”, ืชืฆื˜ืจื›ื• ืœื‘ื—ื•ืŸ ืืช ืกื•ื’ InnerException ื•ืœื›ืชื•ื‘ ืื ืœืฉืจืฉืจ ืืช ืขืฆืžื›ื ื‘ืชื•ืš ื‘ืœื•ืง catch ืื—ื“ ืื• ืœื”ืฉืชืžืฉ ื‘-catch when construct, ื‘ืžืงื•ื ื‘ืฉืจืฉืจืช ื‘ืœื•ืงื™ ื”-catch ื”ืžื•ื›ืจืช ื™ื•ืชืจ ื‘ืขื•ืœื C#.

ื’ื ื”ื“ื•ื’ืžืื•ืช ื”ืฉืœื™ืฉื™ืช ื•ื”ืื—ืจื•ื ื” ืžืกื•ืžื ื•ืช ื›ื’ืจื•ืขื•ืช ืžืื•ืชื” ืกื™ื‘ื” ื•ืžื›ื™ืœื•ืช ืืช ื›ืœ ืื•ืชืŸ ื”ื‘ืขื™ื•ืช.

ื”ืฉื™ื˜ื•ืช WhenAny ื•-WhenAll ื ื•ื—ื•ืช ื‘ืžื™ื•ื—ื“ ืœื”ืžืชื ื” ืœืงื‘ื•ืฆืช ืžืฉื™ืžื•ืช; ื”ืŸ ืขื•ื˜ืคื•ืช ืงื‘ื•ืฆืช ืžืฉื™ืžื•ืช ืœืื—ื“, ืืฉืจ ื™ื•ืคืขืœ ืื• ื›ืืฉืจ ืžืฉื™ืžื” ืžื”ืงื‘ื•ืฆื” ืชื•ืคืขืœ ืœืจืืฉื•ื ื”, ืื• ื›ืืฉืจ ื›ื•ืœืŸ ื”ืฉืœื™ืžื• ืืช ื”ื‘ื™ืฆื•ืข ืฉืœื”ืŸ.

ืขืฆื™ืจืช ืฉืจืฉื•ืจื™ื

ืžืกื™ื‘ื•ืช ืฉื•ื ื•ืช, ื™ื™ืชื›ืŸ ืฉื™ื”ื™ื” ืฆื•ืจืš ืœื”ืคืกื™ืง ืืช ื”ื–ืจื™ืžื” ืœืื—ืจ ืชื—ื™ืœืชื”. ื™ืฉื ืŸ ืžืกืคืจ ื“ืจื›ื™ื ืœืขืฉื•ืช ื–ืืช. ืœืžื—ืœืงื” Thread ื™ืฉ ืฉืชื™ ืฉื™ื˜ื•ืช ื‘ืขืœื•ืช ืฉื ืžืชืื™ื: ื”ืคืœื” ะธ ืœื”ืคืจื™ืข. ื”ืจืืฉื•ืŸ ืžืื•ื“ ืœื ืžื•ืžืœืฅ ืœืฉื™ืžื•ืฉ, ื›ื™ ืœืื—ืจ ื”ืชืงืฉืจื•ืช ืืœื™ื• ื‘ื›ืœ ืจื’ืข ืืงืจืื™, ื‘ืžื”ืœืš ืขื™ื‘ื•ื“ ืฉืœ ื›ืœ ื”ื•ืจืื”, ืชื™ื–ืจืง ื—ืจื™ื’ื” ThreadAbortedException. ืืชื” ืœื ืžืฆืคื” ืฉื™ื•ืฆื ื—ืจื™ื’ ื›ื–ื” ื›ืฉืžื’ื“ื™ืœื™ื ื›ืœ ืžืฉืชื ื” ืžืกืคืจ ืฉืœื, ื ื›ื•ืŸ? ื•ื›ืืฉืจ ืžืฉืชืžืฉื™ื ื‘ืฉื™ื˜ื” ื–ื•, ื–ื”ื• ืžืฆื‘ ืžืื•ื“ ืืžื™ืชื™. ืื ืืชื” ืฆืจื™ืš ืœืžื ื•ืข ืžื”-CLR ืœื™ืฆื•ืจ ื—ืจื™ื’ ื›ื–ื” ื‘ืงื˜ืข ืžืกื•ื™ื ืฉืœ ืงื•ื“, ืืชื” ื™ื›ื•ืœ ืœืขื˜ื•ืฃ ืื•ืชื• ื‘ืฉื™ื—ื•ืช Thread.BeginCriticalRegion, Thread.EndCriticalRegion. ื›ืœ ืงื•ื“ ืฉื ื›ืชื‘ ื‘ื‘ืœื•ืง ืกื•ืคื™ืช ืขื˜ื•ืฃ ื‘ืงืจื™ืื•ืช ื›ืืœื”. ืžืกื™ื‘ื” ื–ื•, ื‘ืžืขืžืงื™ ืงื•ื“ ื”ืžืกื’ืจืช ื ื™ืชืŸ ืœืžืฆื•ื ื‘ืœื•ืงื™ื ืขื ื ื™ืกื™ื•ืŸ ืจื™ืง, ืืš ืœื ืจื™ืง ืœื‘ืกื•ืฃ. ืžื™ืงืจื•ืกื•ืคื˜ ืœื ืžืขื•ื“ื“ืช ืฉื™ื˜ื” ื–ื• ืขื“ ื›ื“ื™ ื›ืš ืฉื”ื ืœื ื›ืœืœื• ืื•ืชื” ื‘ืœื™ื‘ืช .net.

ืฉื™ื˜ืช ื”ืคืกื™ืง ืคื•ืขืœืช ื‘ืฆื•ืจื” ืฆืคื•ื™ื” ื™ื•ืชืจ. ื–ื” ื™ื›ื•ืœ ืœืงื˜ื•ืข ืืช ื”ืฉืจืฉื•ืจ ืขื ื—ืจื™ื’ ื—ืจื™ื’ื” ืžื•ืคืจืขืช ืฉืจืฉื•ืจ ืจืง ื‘ืื•ืชื ืจื’ืขื™ื ืฉื‘ื”ื ื”ืฉืจืฉื•ืจ ื ืžืฆื ื‘ืžืฆื‘ ื”ืžืชื ื”. ื”ื•ื ื ื›ื ืก ืœืžืฆื‘ ื–ื” ื‘ื–ืžืŸ ืชืœื™ื™ื” ื‘ื–ืžืŸ ื”ืžืชื ื” ืœ-WitHandle, ืœื ืขื™ืœื” ืื• ืœืื—ืจ ื”ืชืงืฉืจื•ืช ืœ-Thread.Sleep.

ืฉืชื™ ื”ืืคืฉืจื•ื™ื•ืช ืฉืชื•ืืจื• ืœืขื™ืœ ื”ืŸ ื’ืจื•ืขื•ืช ื‘ื’ืœืœ ื—ื•ืกืจ ื”ื ื™ื‘ื•ื™ ืฉืœื”ืŸ. ื”ืคืชืจื•ืŸ ื”ื•ื ืœื”ืฉืชืžืฉ ื‘ืžื‘ื ื” CancellationToken ื•ื›ื™ืชื” CancellationTokenSource. ื”ื ืงื•ื“ื” ื”ื™ื ื›ื–ื•: ื ื•ืฆืจ ืžื•ืคืข ืฉืœ ื”ืžื—ืœืงื” CancellationTokenSource ื•ืจืง ืžื™ ืฉื‘ื‘ืขืœื•ืชื• ื™ื›ื•ืœ ืœืขืฆื•ืจ ืืช ื”ืคืขื•ืœื” ืขืœ ื™ื“ื™ ืงืจื™ืื” ืœืžืชื•ื“ื” ื‘ื™ื˜ื•ืœ. ืจืง ื”-CancelationToken ืžื•ืขื‘ืจ ืœืคืขื•ืœื” ืขืฆืžื”. ื‘ืขืœื™ CancellationToken ืื™ื ื ื™ื›ื•ืœื™ื ืœื‘ื˜ืœ ืืช ื”ืคืขื•ืœื” ื‘ืขืฆืžื, ืืœื ื™ื›ื•ืœื™ื ืจืง ืœื‘ื“ื•ืง ืื ื”ืคืขื•ืœื” ื‘ื•ื˜ืœื”. ื™ืฉ ืชื›ื•ื ื” ื‘ื•ืœื™ืื ื™ืช ืขื‘ื•ืจ ื–ื” IsCancelationRequested ื•ืฉื™ื˜ื” ThrowIfCancelRequested. ื”ืื—ืจื•ืŸ ื™ื–ืจื•ืง ื—ืจื™ื’ TaskCancelledException ืื ื”ืฉื™ื˜ื” Cancel ื ืงืจืื” ื‘ืžื•ืคืข ืฉืœ CancellationToken ืฉื”ื•ืœืš ืœืชื•ื›ื™. ื•ื–ื• ื”ืฉื™ื˜ื” ืฉืื ื™ ืžืžืœื™ืฅ ืœื”ืฉืชืžืฉ ื‘ื”. ื–ื”ื• ืฉื™ืคื•ืจ ื‘ื™ื—ืก ืœืืคืฉืจื•ื™ื•ืช ื”ืงื•ื“ืžื•ืช ืขืœ ื™ื“ื™ ื”ืฉื’ืช ืฉืœื™ื˜ื” ืžืœืื” ื‘ืื™ื–ื• ื ืงื•ื“ื” ื ื™ืชืŸ ืœื‘ื˜ืœ ืคืขื•ืœืช ื—ืจื™ื’ื”.

ื”ืืคืฉืจื•ืช ื”ืื›ื–ืจื™ืช ื‘ื™ื•ืชืจ ืœืขืฆื™ืจืช ืฉืจืฉื•ืจ ื”ื™ื ืœืงืจื•ื ืœืคื•ื ืงืฆื™ื” ืฉืœ Win32 API TerminateThread. ื”ืชื ื”ื’ื•ืช ื”-CLR ืœืื—ืจ ืงืจื™ืื” ืœืคื•ื ืงืฆื™ื” ื–ื• ืขืฉื•ื™ื” ืœื”ื™ื•ืช ื‘ืœืชื™ ืฆืคื•ื™ื”. ื‘-MSDN ื ื›ืชื‘ ืขืœ ื”ืคื•ื ืงืฆื™ื” ื”ื–ื•: "TerminateThread ื”ื™ื ืคื•ื ืงืฆื™ื” ืžืกื•ื›ื ืช ืฉื™ืฉ ืœื”ืฉืชืžืฉ ื‘ื” ืจืง ื‘ืžืงืจื™ื ื”ืงื™ืฆื•ื ื™ื™ื ื‘ื™ื•ืชืจ. "

ื”ืžืจืช API ืžื“ื•ืจ ืงื•ื“ื ืœ-Task Based ื‘ืฉื™ื˜ืช FromAsync

ืื ื™ืชืžื–ืœ ืžื–ืœืš ืœืขื‘ื•ื“ ืขืœ ืคืจื•ื™ืงื˜ ืฉื”ืชื—ื™ืœ ืœืื—ืจ ื”ืฆื’ืช ืžืฉื™ืžื•ืช ื•ื”ืคืกื™ืง ืœื’ืจื•ื ืื™ืžื” ืฉืงื˜ื” ืขื‘ื•ืจ ืจื•ื‘ ื”ืžืคืชื—ื™ื, ืื– ืœื ืชืฆื˜ืจืš ืœื”ืชืžื•ื“ื“ ืขื ื”ืจื‘ื” ืžืžืฉืงื™ 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 ืžื“ื•ืจ ืงื•ื“ื ืœ-Task Based ื‘ืืžืฆืขื•ืช ืžื—ืœืงื” TaskCompletionSource

ื›ืœื™ ื—ืฉื•ื‘ ื ื•ืกืฃ ืฉื™ืฉ ืœืงื—ืช ื‘ื—ืฉื‘ื•ืŸ ื”ื•ื ื”ื›ื™ืชื” TaskCompletionSource. ืžื‘ื—ื™ื ืช ืคื•ื ืงืฆื™ื•ืช, ืžื˜ืจื” ื•ืขื™ืงืจื•ืŸ ื”ืคืขื•ืœื”, ื–ื” ืื•ืœื™ ืžื–ื›ื™ืจ ืงืฆืช ืืช ืฉื™ื˜ืช RegisterWaitForSingleObject ืฉืœ ื”ืžื—ืœืงื” ThreadPool, ืขืœื™ื” ื›ืชื‘ืชื™ ืœืžืขืœื”. ื‘ืืžืฆืขื•ืช ืžื—ืœืงื” ื–ื•, ืืชื” ื™ื›ื•ืœ ื‘ืงืœื•ืช ื•ื‘ื ื•ื—ื•ืช ืœืขื˜ื•ืฃ ืžืžืฉืงื™ API ืืกื™ื ื›ืจื•ื ื™ื™ื ื™ืฉื ื™ื ื‘-Tasks.

ืืชื” ืชื’ื™ื“ ืฉื›ื‘ืจ ื“ื™ื‘ืจืชื™ ืขืœ ืฉื™ื˜ืช FromAsync ืฉืœ ื”ืžื—ืœืงื” TaskFactory ื”ืžื™ื•ืขื“ืช ืœืžื˜ืจื•ืช ืืœื•. ื›ืืŸ ื ืฆื˜ืจืš ืœื–ื›ื•ืจ ืืช ื›ืœ ื”ื”ื™ืกื˜ื•ืจื™ื” ืฉืœ ื”ืคื™ืชื•ื— ืฉืœ ืžื•ื“ืœื™ื ืืกื™ื ื›ืจื•ื ื™ื™ื ื‘-.net ืฉื”ืฆื™ืขื” ืžื™ืงืจื•ืกื•ืคื˜ ื‘ืžื”ืœืš 15 ื”ืฉื ื™ื ื”ืื—ืจื•ื ื•ืช: ืœืคื ื™ ื”-TAP (TAP), ื”ื™ื” ื”-Asynchronous Programming Pattern (APP), ืืฉืจ ื”ื™ื” ืขืœ ืฉื™ื˜ื•ืช ืœื”ืชื—ื™ืœDoSomething ื—ื•ื–ืจ IAsyncResult ื•ืฉื™ื˜ื•ืช ืกื•ึนืฃDoSomething ืฉืžืงื‘ืœ ืืช ื–ื” ื•ืขื‘ื•ืจ ืžื•ืจืฉืช ื”ืฉื ื™ื ื”ืœืœื• ืฉื™ื˜ืช FromAsync ื”ื™ื ืคืฉื•ื˜ ืžื•ืฉืœืžืช, ืื‘ืœ ืขื ื”ื–ืžืŸ, ื”ื™ื ื”ื•ื—ืœืคื” ื‘-Event Based Asynchronous Pattern (EAP), ืืฉืจ ื”ื ื™ื— ื›ื™ ืื™ืจื•ืข ื™ื•ืขืœื” ื›ืืฉืจ ื”ืคืขื•ืœื” ื”ื-ืกื™ื ื›ืจื•ื ื™ืช ืชื•ืฉืœื.

TaskCompletionSource ืžื•ืฉืœื ืขื‘ื•ืจ ื’ืœื™ืฉืช ืžืฉื™ืžื•ืช ื•ืžืžืฉืงื™ API ืžื“ื•ืจ ืงื•ื“ื ืฉื ื‘ื ื• ืกื‘ื™ื‘ ืžื•ื“ืœ ื”ืื™ืจื•ืข. ื”ืžื”ื•ืช ืฉืœ ืขื‘ื•ื“ืชื• ื”ื™ื ื›ื“ืœืงืžืŸ: ืœืื•ื‘ื™ื™ืงื˜ ืžืžื—ืœืงื” ื–ื• ื™ืฉ ืžืืคื™ื™ืŸ ืฆื™ื‘ื•ืจื™ ืžืกื•ื’ Task, ืฉื ื™ืชืŸ ืœืฉืœื•ื˜ ื‘ืžืฆื‘ื• ื‘ืืžืฆืขื•ืช ืฉื™ื˜ื•ืช SetResult, SetException ื•ื›ื•' ืฉืœ ื”ืžื—ืœืงื” TaskCompletionSource. ื‘ืžืงื•ืžื•ืช ืฉื‘ื”ื ืื•ืคืจื˜ื•ืจ ื”ื”ืžืชื ื” ื”ื•ื—ืœ ืขืœ ืžืฉื™ืžื” ื–ื•, ื”ื•ื ื™ื‘ื•ืฆืข ืื• ื™ื™ื›ืฉืœ ืขื ื—ืจื™ื’ื” ื‘ื”ืชืื ืœืฉื™ื˜ื” ืฉื”ื•ื—ืœื” ืขืœ ื”-TaskCompletionSource. ืื ื–ื” ืขื“ื™ื™ืŸ ืœื ื‘ืจื•ืจ, ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžื” ื–ื• ืฉืœ ืงื•ื“, ืฉื‘ื” ืื™ื–ืฉื”ื• ืžืžืฉืง API ื™ืฉืŸ ืฉืœ EAP ืขื˜ื•ืฃ ื‘ืžืฉื™ืžื” ื‘ืืžืฆืขื•ืช 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, ื›ืžื• ืื•ืคืจื˜ื•ืจ ื”ื—ื–ืจืช ืชืฉื•ืื”, ืžื™ื™ืฆืจื™ื ืžื”ืฉื™ื˜ื” ืžื›ื•ื ืช ืžืฆื‘, ื•ื–ื•ื”ื™ ื™ืฆื™ืจืช ืื•ื‘ื™ื™ืงื˜ ื—ื“ืฉ, ืฉื›ืžืขื˜ ืชืžื™ื“ ืื™ื ื• ื—ืฉื•ื‘, ืืš ื‘ืžืงืจื™ื ื ื“ื™ืจื™ื ื”ื™ื ืขืœื•ืœื” ืœื™ืฆื•ืจ ื‘ืขื™ื”. ื”ืžืงืจื” ื”ื–ื” ืขืฉื•ื™ ืœื”ื™ื•ืช ืฉื™ื˜ื” ืฉื ืงืจืืช ืœืขืชื™ื ืงืจื•ื‘ื•ืช ืžืื•ื“, ืื ื—ื ื• ืžื“ื‘ืจื™ื ืขืœ ืขืฉืจื•ืช ื•ืžืื•ืช ืืœืคื™ ืฉื™ื—ื•ืช ื‘ืฉื ื™ื™ื”. ืื ืฉื™ื˜ื” ื›ื–ื• ื›ืชื•ื‘ื” ื‘ืฆื•ืจื” ื›ื–ื• ืฉื‘ืจื•ื‘ ื”ืžืงืจื™ื ื”ื™ื ืžื—ื–ื™ืจื” ืชื•ืฆืื” ืขื•ืงืคืช ืืช ื›ืœ ืฉื™ื˜ื•ืช ื”-await, ืื– .NET ืžืกืคืง ื›ืœื™ ืœื™ื™ืขืœ ื–ืืช - ืžื‘ื ื” ValueTask. ื›ื“ื™ ืœื”ื‘ื”ื™ืจ ืืช ื–ื”, ื‘ื•ืื• ื ืกืชื›ืœ ืขืœ ื“ื•ื’ืžื” ืœืฉื™ืžื•ืฉ ื‘ื•: ื™ืฉ ืžื˜ืžื•ืŸ ืฉืื ื—ื ื• ื”ื•ืœื›ื™ื ืืœื™ื• ืœืขืชื™ื ืงืจื•ื‘ื•ืช ืžืื•ื“. ื™ืฉ ื‘ื• ื›ืžื” ืขืจื›ื™ื ื•ืื– ืื ื—ื ื• ืคืฉื•ื˜ ืžื—ื–ื™ืจื™ื ืื•ืชื; ืื ืœื, ืื– ืื ื—ื ื• ื”ื•ืœื›ื™ื ืœืื™ื–ื” IO ืื™ื˜ื™ ื›ื“ื™ ืœืงื‘ืœ ืื•ืชื. ืื ื™ ืจื•ืฆื” ืœืขืฉื•ืช ืืช ื”ืื—ืจื•ืŸ ื‘ืฆื•ืจื” ืืกื™ื ื›ืจื•ื ื™ืช, ืžื” ืฉืื•ืžืจ ืฉื›ืœ ื”ืฉื™ื˜ื” ืžืชื‘ืจืจืช ื›ื-ืกื™ื ื›ืจื•ื ื™ืช. ืœืคื™ื›ืš, ื”ื“ืจืš ื”ื‘ืจื•ืจื” ืœื›ืชื™ื‘ืช ื”ืฉื™ื˜ื” ื”ื™ื ื›ื“ืœืงืžืŸ:

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

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

ื‘ื’ืœืœ ื”ืจืฆื•ืŸ ืœื™ื™ืขืœ ืžืขื˜, ื•ื—ืฉืฉ ืงืœ ืžืžื” ืฉืจื•ื–ืœื™ืŸ ืชื™ื™ืฆืจ ื‘ืขืช ื”ื™ื“ื•ืจ ื”ืงื•ื“ ื”ื–ื”, ืืชื” ื™ื›ื•ืœ ืœืฉื›ืชื‘ ืืช ื”ื“ื•ื’ืžื” ื”ื–ื• ื‘ืื•ืคืŸ ื”ื‘ื:

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 ื”ื‘ื ืฉื”ื™ื™ืชื™ ืจื•ืฆื” ืœืฉืงื•ืœ ื”ื•ื ื”ืžื—ืœืงื” ืžืชื–ืžืŸ ืžืฉื™ืžื•ืช ื•ื ื’ื–ืจื•ืชื™ื•. ื›ื‘ืจ ื”ื–ื›ืจืชื™ ืœืžืขืœื” ืฉืœ-TPL ื™ืฉ ืืช ื”ื™ื›ื•ืœืช ืœื ื”ืœ ืืกื˜ืจื˜ื’ื™ื•ืช ืœื”ืคืฆืช ืžืฉื™ืžื•ืช ืขืœ ืคื ื™ ืืฉื›ื•ืœื•ืช. ืืกื˜ืจื˜ื’ื™ื•ืช ื›ืืœื” ืžื•ื’ื“ืจื•ืช ื‘ืฆืืฆืื™ ื”ืžื—ืœืงื” TaskScheduler. ื›ืžืขื˜ ื›ืœ ืืกื˜ืจื˜ื’ื™ื” ืฉืื•ืœื™ ืชืฆื˜ืจืš ืชืžืฆื ื‘ืกืคืจื™ื™ื”. ืชื•ืกืคื•ืช ืžืงื‘ื™ืœื•ืช ืชื•ืกืคื•ืช, ืคื•ืชื— ืขืœ ื™ื“ื™ ืžื™ืงืจื•ืกื•ืคื˜, ืืš ืื™ื ื• ื—ืœืง ืž-.NET, ืืœื ืžืกื•ืคืง ื›ื—ื‘ื™ืœืช Nuget. ื‘ื•ืื• ื ืกืชื›ืœ ื‘ืงืฆืจื” ืขืœ ื›ืžื” ืžื”ื:

  • CurrentThreadTaskScheduler - ืžื‘ืฆืข ืžืฉื™ืžื•ืช ื‘ืฉืจืฉื•ืจ ื”ื ื•ื›ื—ื™
  • LimitedConcurrencyLevel Task Scheduler - ืžื’ื‘ื™ืœ ืืช ืžืกืคืจ ื”ืžืฉื™ืžื•ืช ื”ืžื‘ื•ืฆืขื•ืช ื‘ื• ื–ืžื ื™ืช ืขืœ ื™ื“ื™ ืคืจืžื˜ืจ N, ื”ืžืงื•ื‘ืœ ื‘ื‘ื ืื™
  • OrderedTaskScheduler - ืžื•ื’ื“ืจ ื›- LimitedConcurrencyLevelTaskScheduler(1), ื›ืš ืฉื”ืžืฉื™ืžื•ืช ื™ื‘ื•ืฆืขื• ื‘ืจืฆืฃ.
  • WorkStealingTaskScheduler - ืžื™ื™ืฉื ื’ื ื™ื‘ืช ืขื‘ื•ื“ื” ื’ื™ืฉื” ืœื—ืœื•ืงืช ืžืฉื™ืžื•ืช. ื‘ืขื™ืงืจื• ืฉืœ ื“ื‘ืจ ื–ื”ื• ThreadPool ื ืคืจื“. ืคื•ืชืจ ืืช ื”ื‘ืขื™ื” ืฉื‘-.NET ThreadPool ื”ื™ื ืžื—ืœืงื” ืกื˜ื˜ื™ืช, ืื—ืช ืœื›ืœ ื”ื™ื™ืฉื•ืžื™ื, ืžื” ืฉืื•ืžืจ ืฉืขื•ืžืก ื™ืชืจ ืฉืœื” ืื• ืฉื™ืžื•ืฉ ืœื ื ื›ื•ืŸ ื‘ื—ืœืง ืื—ื“ ืฉืœ ื”ืชื•ื›ื ื™ืช ืขืœื•ืœ ืœื”ื•ื‘ื™ืœ ืœืชื•ืคืขื•ืช ืœื•ื•ืื™ ื‘ื—ืœืง ืื—ืจ. ื™ืชืจื” ืžื›ืš, ืงืฉื” ืžืื•ื“ ืœื”ื‘ื™ืŸ ืืช ื”ืกื™ื‘ื” ืœืœื™ืงื•ื™ื™ื ื›ืืœื”. ื–ึถื”. ื™ื™ืชื›ืŸ ืฉื™ื”ื™ื” ืฆื•ืจืš ืœื”ืฉืชืžืฉ ื‘-WorkStealingTaskSchedulers ื ืคืจื“ื™ื ื‘ื—ืœืงื™ื ืžื”ืชื•ื›ื ื™ืช ืฉื‘ื”ื ื”ืฉื™ืžื•ืฉ ื‘-ThreadPool ืขืฉื•ื™ ืœื”ื™ื•ืช ืื’ืจืกื™ื‘ื™ ื•ื‘ืœืชื™ ืฆืคื•ื™.
  • QueuedTaskScheduler โ€” ืžืืคืฉืจ ืœืš ืœื‘ืฆืข ืžืฉื™ืžื•ืช ืœืคื™ ื›ืœืœื™ ืชื•ืจ ืขื“ื™ืคื•ืช
  • ThreadPerTaskScheduler - ื™ื•ืฆืจ ืฉืจืฉื•ืจ ื ืคืจื“ ืขื‘ื•ืจ ื›ืœ ืžืฉื™ืžื” ืฉืžืชื‘ืฆืขืช ื‘ื•. ื™ื›ื•ืœ ืœื”ื™ื•ืช ืฉื™ืžื•ืฉื™ ืขื‘ื•ืจ ืžืฉื™ืžื•ืช ืฉืœื•ืงื— ื–ืžืŸ ืจื‘ ื‘ืื•ืคืŸ ื‘ืœืชื™ ืฆืคื•ื™ ืœื‘ื™ืฆื•ืข.

ื™ืฉ ืžืคื•ืจื˜ ื˜ื•ื‘ ืžืืžืจ ืขืœ TaskSchedulers ื‘ื‘ืœื•ื’ ืฉืœ ืžื™ืงืจื•ืกื•ืคื˜.

ืœื ื™ืคื•ื™ ื‘ืื’ื™ื ื ื•ื— ืฉืœ ื›ืœ ืžื” ืฉืงืฉื•ืจ ืœืžืฉื™ืžื•ืช, ืœ-Visual Studio ื™ืฉ ื—ืœื•ืŸ ืžืฉื™ืžื•ืช. ื‘ื—ืœื•ืŸ ื–ื” ืชื•ื›ืœื• ืœืจืื•ืช ืืช ื”ืžืฆื‘ ื”ื ื•ื›ื—ื™ ืฉืœ ื”ืžืฉื™ืžื” ื•ืœืงืคื•ืฅ ืœืฉื•ืจืช ื”ืงื•ื“ ื”ืžื‘ืฆืขืช ื›ืขืช.

.NET: ื›ืœื™ื ืœืขื‘ื•ื“ื” ืขื ืจื™ื‘ื•ื™ ื”ืฉื—ืœื•ืช ื•ื-ืกื™ื ื›ืจื•ืŸ. ื—ืœืง 1

PLinq ื•ื”ืžื—ืœืงื” ื”ืžืงื‘ื™ืœื”

ื‘ื ื•ืกืฃ ืœ-Tasks ื•ืœื›ืœ ืžื” ืฉื ืืžืจ ืขืœื™ื”ื, ื™ืฉ ืขื•ื“ ืฉื ื™ ื›ืœื™ื ืžืขื ื™ื™ื ื™ื ื‘-.NET: PLinq (Linq2Parallel) ื•ื”ืžื—ืœืงื” Parallel. ื”ืจืืฉื•ืŸ ืžื‘ื˜ื™ื— ื‘ื™ืฆื•ืข ืžืงื‘ื™ืœ ืฉืœ ื›ืœ ืคืขื•ืœื•ืช Linq ื‘ืžืกืคืจ ืฉืจืฉื•ืจื™ื. ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืืช ืžืกืคืจ ื”ืฉืจืฉื•ืจื™ื ื‘ืืžืฆืขื•ืช ืฉื™ื˜ืช ื”ื”ืจื—ื‘ื” WithDegreeOfParallelism. ืœืžืจื‘ื” ื”ืฆืขืจ, ืœืจื•ื‘ ืœ-PLinq ื‘ืžืฆื‘ ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ืื™ืŸ ืžืกืคื™ืง ืžื™ื“ืข ืขืœ ื”ืคื ื™ืžื™ื•ืช ืฉืœ ืžืงื•ืจ ื”ื ืชื•ื ื™ื ืฉืœืš ื›ื“ื™ ืœืกืคืง ืฉื™ืคื•ืจ ืžื”ื™ืจื•ืช ืžืฉืžืขื•ืชื™, ืžืฆื“ ืฉื ื™, ืขืœื•ืช ื”ื ื™ืกื™ื•ืŸ ื ืžื•ื›ื” ืžืื•ื“: ืืชื” ืจืง ืฆืจื™ืš ืœื”ืชืงืฉืจ ืœืฉื™ื˜ืช AsParallel ืœืคื ื™ ืฉืจืฉืจืช ืฉื™ื˜ื•ืช Linq ื•ื”ืคืขืœืช ืžื‘ื—ื ื™ ื‘ื™ืฆื•ืขื™ื. ื™ืชืจื” ืžื›ืš, ื ื™ืชืŸ ืœื”ืขื‘ื™ืจ ืžื™ื“ืข ื ื•ืกืฃ ืœ-PLinq ืขืœ ืื•ืคื™ ืžืงื•ืจ ื”ื ืชื•ื ื™ื ืฉืœืš ื‘ืืžืฆืขื•ืช ืžื ื’ื ื•ืŸ ื”ืžื—ื™ืฆื•ืช. ืืชื” ื™ื›ื•ืœ ืœืงืจื•ื ืขื•ื“ ื›ืืŸ ะธ ื›ืืŸ.

ื”ืžื—ืœืงื” Parallel static ืžืกืคืงืช ืฉื™ื˜ื•ืช ืœืื™ื˜ืจืฆื™ื” ื“ืจืš ืื•ืกืฃ Foreach ื‘ืžืงื‘ื™ืœ, ื‘ื™ืฆื•ืข ืœื•ืœืืช For ื•ื‘ื™ืฆื•ืข ืžืกืคืจ ื ืฆื™ื’ื™ื ื‘-Invoke ืžืงื‘ื™ืœ. ื‘ื™ืฆื•ืข ื”ืฉืจืฉื•ืจ ื”ื ื•ื›ื—ื™ ื™ื•ืคืกืง ืขื“ ืœื”ืฉืœืžืช ื”ื—ื™ืฉื•ื‘ื™ื. ื ื™ืชืŸ ืœื”ื’ื“ื™ืจ ืืช ืžืกืคืจ ื”ืฉืจืฉื•ืจื™ื ืขืœ ื™ื“ื™ ื”ืขื‘ืจืช ParallelOptions ื›ืืจื’ื•ืžื ื˜ ื”ืื—ืจื•ืŸ. ืืชื” ื™ื›ื•ืœ ื’ื ืœืฆื™ื™ืŸ TaskScheduler ื•-CancelationToken ื‘ืืžืฆืขื•ืช ืืคืฉืจื•ื™ื•ืช.

ืžืžืฆืื™ื

ื›ืฉื”ืชื—ืœืชื™ ืœื›ืชื•ื‘ ืžืืžืจ ื–ื” ืขืœ ืกืžืš ื—ื•ืžืจื™ ื”ื“ื•"ื— ืฉืœื™ ื•ื”ืžื™ื“ืข ืฉืืกืคืชื™ ื‘ืžื”ืœืš ืขื‘ื•ื“ืชื™ ืœืื—ืจื™ื•, ืœื ืฆื™ืคื™ืชื™ ืฉื™ื”ื™ื” ื›ืœ ื›ืš ื”ืจื‘ื” ืžืžื ื•. ื›ืขืช, ื›ืืฉืจ ืขื•ืจืš ื”ื˜ืงืกื˜ ื‘ื• ืื ื™ ืžืงืœื™ื“ ืืช ื”ืžืืžืจ ื”ื–ื” ื‘ืชื•ื›ื—ื” ืื•ืžืจ ืœื™ ืฉืขืžื•ื“ 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

ื”ื•ืกืคืช ืชื’ื•ื‘ื”