áá±á¬áºááá¯ááááºááœáẠáááºáá¬ážáá±á¬ áá¬áá¬ááŒááºááá¯áá»áẠHabr ááœáẠáá°áááºážáá±á¬ááºážáá«ážááᯠáá»áœááºá¯ááºáá¯ááºáá±áá±áá«áááºá
á€áá±áá¬ááŸáá·áº ááá¯ááááºááᯠáá
á±á¬áá·áºááá¯ááºážáá²á ááá¯á·ááá¯áẠáááºážááá¯áá¯ááºáá±á¬ááºáá±ááá·áº áá°áá
áºáá»á¬ážá
áœá¬ááœáẠááŒá®ážáá¬ážáá±á¬á¡áá¯ááºáá»á¬ážááᯠááá¯ááºážááŒá¬ážááẠáááá¯á¡ááºáá² áá
áºáá¯áá¯ááᯠáááŒáá¯ááºáááºážáá¯ááºáá±á¬ááºááẠááá¯á¡ááºáááºááŸá¬ ááœááºáá»á°áá¬áááœááºážáá¬ážáá®á áááºááŸááá²á·áááºá áá°ááá¯á· ááœááºážáá¬ážáá¬áá¬áá²á·á¡áá»áŸ áá®ááá¯á¡ááºáá»ááºá á¡áááºážááŒááºáá¬áááºáá¬ááŸááá¬áááºá ááᯠ2019 ááœááºá 8-core Intel Core áááá¯áááºáá¬áá«ááŸááá±á¬ áááºááºáá±á¬á·áá
áºáá¯á¶ážááœáẠá€áá±á¬ááºážáá«ážááᯠáá»áœááºá¯ááºááá¯ááºáá±áááºá áá¯ááºáááºážá
ááºáá±á«ááºáž áá
áºáá¬áá»á±á¬áºááẠá¡ááŒáá¯ááºáá¯ááºáá±á¬ááºáá±ááŒá®áž áá±á¬ááºáááºá¡ááŒá±á¬ááºážá¡áá¬áá»á¬ážááẠááŒá
áºáááºá á¡áá®ážáá¬ážááœáẠááœááºáá²á·ááá·áº ááŸá
áºá¡áááºážáááºá áááºáá²á·áá±á¬ á¡áááºážááẠáá
áºáááºáá±á¬ áá¯ááºážáá
áºáá¯á¶áž ááŸáááŒá®áž áááºážááœáẠ8-core áááá¯áááºáᬠáá«ááŸááááºá á¡ááŒá±á¬ááºážá¡áá¬áááºážááŒá
áºáá»á¬ážááẠ16-core áááá¯áááºáá¬áá»á¬ážáá«ááŸááá±á¬ ááá¯ááŸá
áºá á¡áááºááá
áááºáá¯ááºážáá»á¬ážááœáẠáááºážááá¯á·áá
á¬áá±ážááá¬áá»á¬ážááᯠááá±á¬áá»ááá·áº áá±á¬ááºážáá«ážáá»á¬ážááŸáá·áº áá®áá®ááá¯áá»á¬áž ááŒáá·áºááŸááºáá±áááºá MS Azure ááẠáá
áºáá¬áá®áá»áŸáẠ$20 áááºáááºážáá±á¬ 128 core áááá¯áááºáá¬ááŸáá·áº 2 TB RAM áá«ááá·áº virtual machine áá
áºáá¯ááᯠáá±ážáá«áááºá áá¶ááá±á¬ááºážá
áœá¬áá²á áá»ááºáá»áŸááºáá»á¬ážáá¡ááŒááºá¡ááŸááºá¡áá»áá¯ážáááºáá±á¬ááºááŸá¯ááá¯á
á®áá¶ááá·áºááœá²ááá¯ááºááŒááºážáááŸááá²á¡ááŒáá·áºáá¯á¶ážááá¯áá¯ááºáá°ááŒá®ážá€áá«áá«ááá¯á¡áá¯á¶ážáá»áááºáááŒá
áºááá¯ááºáá«á
áá±á«áá¬áááá¬
áá¯ááºáááºážá
áẠ- OS á¡áá¬ááá¹áá¯á áá®ážááŒá¬ážááááºá
á¬áá±áá¬á á
á¬ááœá²áá»á¬ážáá«ááŸááááºá
áá»áẠ- OS á¡áá¬ááá¹áá¯áá
áºáá¯á áá¯ááºáá±á¬ááºááŸá¯áá¡áá±ážáá¯á¶ážáá°áá
áºá áá¯ááºáááºážá
ááºáá
áºáá¯ááá
áºá
áááºáá
áºááá¯ááºážá thread áá»á¬ážááẠáá¯ááºáááºážá
ááºáá
áºáá¯á¡ááœááºáž áááºážááá¯á·á¡áá»ááºážáá»ááºáž áááºááá¯áá®ááŸáá·áº á¡ááŒá¬ážá¡áááºážá¡ááŒá
áºáá»á¬ážááᯠáá»áŸáá±áááºá
Multitasking - OS ááá¯ááºááá¯ááºááŸá¯á áá¯ááºáááºážá
ááºáá»á¬ážá
áœá¬ááᯠáá
áºááŒáá¯ááºááẠáá¯ááºáá±á¬ááºááá¯ááºááŸá¯
Multi-core - áááá¯áááºáá¬áááá¯ááºááá¯ááºááŸá¯áá
áºáá¯á áá±áá¬áá¯ááºáá±á¬ááºááŒááºážá¡ááœáẠcores á¡áá»á¬ážá¡ááŒá¬ážááá¯á¡áá¯á¶ážááŒá¯ááá¯ááºá
áœááºáž
Multiprocessing - ááœááºáá»á°áá¬áá
áºáá¯á¶ážá ááá¯ááºááá¯ááºááŸá¯á áááá¯áááºáá¬áá»á¬ážá
áœá¬ááŸáá·áº áá
áºááŒáá¯ááºááẠá¡áá¯ááºáá¯ááºááá¯ááºááŸá¯
Multithreading â áá¯ááºáááºážá
ááºáá
áºáá¯á ááá¯ááºááá¯ááºááŸá¯áá
áºáá¯á áá»á¬ážá
áœá¬áá±á¬ threads áá»á¬ážááŒá¬ážááœáẠáá±áá¬áá¯ááºáá±á¬ááºááŒááºážááá¯ááºáᬠááŒáá·áºáá±áá±ážááá¯ááºá
áœááºážá
ááŒáá¯ááºáá°áá«á - á¡áá»áááºáá°áá
áºá¡ááá¯áẠááŸá¯ááºááŸá¬ážááŸá¯áá»á¬ážá
áœá¬ááᯠáá
áºááŒáá¯ááºááẠáá¯ááºáá±á¬ááºááŒááºážá
á¡áá»áá¯ážáá®áá® - á€á
á®áá¶áá±á¬ááºááœááºááŸá¯á ááŒá®ážá
á®ážááŸá¯ááᯠáá
á±á¬áá·áºááá¯ááºážáá² áá¯ááºáá±á¬ááºáá»ááºáá
áºáá¯á¡á¬áž ááœááºáá»ááºááŒááºážá ááœááºáá»ááºááŒááºážáááááºááᯠáá±á¬ááºááá¯ááºážááœáẠáá¯ááºáá±á¬ááºááá¯ááºáááºá
á¥áá á¬
á¡áááá¹áá¬ááºááœáá·áºááá¯áá»ááºá¡á¬ážáá¯á¶ážááẠáá±á¬ááºážááœááºáááºááá¯ááºáá«á á¡áá»áá¯á·á áááºáá±á¬ááºážááŸááºážááŒááẠááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº áá¶áááºá á¬áá»ááºááŒá¯ááºááŒááºážááŸáá·áºáááºáááºááá·áº á¥ááá¬áá áºáá¯á¡á¬áž ááá¬ážáááºááááºáááºáá¬ážáá±á¬áá±á«áá¬áááœáẠáá»áœááºá¯ááºááá·áºááœááºážáá«áááºá á€á¥ááá¬ááœáẠáá¶áááºá á¬áá»ááºááŒá¯ááºááŒááºážááẠáá¯ááºáááºážá ááºáá áºáá¯ááŒá áºáááºá
ááááºá á¬ááŒááºáá±áááºáž (á á®áá®áá°áá« áá®ážááá¯áá»á±á¬ááºáá² áá±á¬ááºáá±áááºáááœááºáá»á°áá¬) áá«á·ááŸá¬ ááẠá áá»á±á¬ááºážááŸáááẠ(á¡áá±á¬ááºáá»á¬áž) áá®ážááá¯áá»á±á¬ááºááŸá¬ á ááºáá á¹á ááºážááœá± á¡áá»á¬ážááŒá®ážááŸáááẠ(IO): áá®ážááá¯á áá±ááœá±ážá¡áá¯ážá áá®ážááá¯áá»á±á¬ááºá áá±áá²áá±áá¹áá¬á áááºá áºááá¯ááœáá·áºááŒá®áž áááºá¡áá¯ážáá áºáá¯á¶ážááᯠáá®ážáá°á¡á±á¬ááºáá á±á¬áá·áºáá² áá®áá±á¬ááºážááá·áºááá¯ááºáá«ááá áºáá»áááºáááºážááœááºá Non-Blocking-IO-Wait) áá±áá²áá±áá¹áá¬áá²á ááŒááºá¥ááœá±ááᯠáááºážáááºááŒá¬ážáá áºáá¯áá² ááœá²ááŒá®áž áááºáá áºáááºáá²á· ááá¯ááºáááºáá á¬áááºážáá¶áá«áẠá) ááŸáá·áº áá¯ááá (á á¬áááºážáá¶áá«áẠá) áááºážáááºááŒá¬áž (Shared Resource) ááᯠááá¯ááºáá¬ážáá«á á¡áᯠáá±ááœá±ážá¡áá¯ážááœáá·áºáá»ááºáá±ááá·áº áááºáá²ááŸá¬ ááá¯á¶áá±á¬ááºáá°áž (Thread áááºááœááºáá±á«ááºážáá«ážááŒááºážá) áá®á¡áá»áááºááŸá¬ ááŒá±á¬áºáá¬ážáá²á· áááºá¡áá¯ážá áá°áá¬áᬠ(ááááºááᯠá á®áá¶ááŒááºáž) á áá«ááŒá¬ááœááºááᯠáá±á¬ááºážááá·áºááá¯ááºáá¬á áá±ááœá±ážá¡áá¯ážááᯠááŸááºážááœáá·áºááŒá®áž áá±áá°áá¬ááᯠááá¯ááºáá²á áœá¬ ááŒáá·áºáá±ááẠ(Blocking-IO-Wat) áá®á¡áá»áááºááŸá¬ áá° áááºážáááºááŒá¬ážááᯠááŒá¬ááœááºáá²á· áá¯ááºááá¯á·ááá±ááá·áºá
ááẠá áááºáá¬á¡áá¯á¶ážááŒá¯ááŒá®áž ááŒááºá¥ááŒá¯ááºáá áºáá¯á¶ážááᯠáá»ááºá áá¬áááŸááá±á¬á·áá±ááá·áº áá áºáá»áááºáááºážááŸá¬áá² ááŒááºá¥á¡áá¬ááᯠááœááºááá¯ááºáá²á·á¡áá»áááºááŸá¬áá±á¬á· ááœá²á áááºááŸá¯ á áá»ááºá áá áºááŒáá¯ááºáááºáááºáž ááŒá áºááœá¬ážáá«áááº- áááºážáááºááŒá¬ážááá¯ááá¯ááºááŒá®áž áááºá¡áá¯ážááᯠá¡áá°áá±ážááá¯ááºáá«á CPU ááẠááœááºááŒá°áá¬á á¡ááŒááºáá¯á¶áž á¡á áááºá¡ááá¯ááºážááŒá áºááŒá®áž IO ááẠá¡áá¬á¡á¬ážáá¯á¶áž ááŸá±ážááœá±ážááœá¬ážáá±á·ááŸááá±á¬ááŒá±á¬áá·áº áááŒá¬ááááá¯áááᯠáááá±á¬ááºáá±á¬ ááŒá±ááŸááºážáá»ááºááŸá¬ IO á០áá±áá¬áá»á¬ážááᯠáááºáá¶áááŸááá»áááºááœáẠCPU ááᯠáá áºá á¯á¶áá áºáá¯ááŒáá·áº ááááºážááá¯ááºáááºááŒá áºáááºá
ááááááºáááºááŒááºáž-
- á¡áááºá omelet ááá¯ááŒááºáááºáá±á ááºááœááºá á¡áááºá¡á á¬ážáá²áááºááŒáá¯ážá á¬ážáá«áá áááºážááẠmultitasking áá¥ááá¬áá áºáá¯ááŒá áºáááºá á¡áá±ážááŒá®ážáá±á¬ ááœá²ááŒá¬ážáá»ááºáá áºáá¯- ááœááºáá»á°áá¬áá»á¬ážááẠáá°áá»á¬ážááẠá€á¡áá¬ááœáẠáá»á¬ážá áœá¬ áá±á¬ááºážááœááºáá«áááºá
- á¥ááá¬- á á¬ážáá±á¬ááºááá¯ááºáá áºáá¯ááœáẠá á¬ážááá¯ááŸá°ážáá»á¬ážá áœá¬ááŸááá±á¬ áá®ážááá¯áá»á±á¬ááºáá áºáᯠ- multi-core ááœááºáá»á°áá¬á
- á á»á±ážáááºá ááºáᬠ- áá±áá¬á ááºáá¬ááŸá food court ááŸá á á¬ážáá±á¬ááºááá¯ááºáá»á¬ážá áœá¬
.NET Tools áá»á¬áž
.NET ááẠá¡ááŒá¬ážá¡áá¬áá»á¬ážá áœá¬ááá¯á·áá²á·ááá¯á· thread áá»á¬ážááŸáá·áº á¡áá¯ááºáá¯ááºáá¬ááœáẠáá±á¬ááºážááœááºáá«áááºá áá¬ážááŸááºážá¡áá áºáá áºáá¯á á®ááœááºá áááºážááẠáááºážááá¯á·ááŸáá·áºáá¯ááºáá±á¬ááºááẠáááááá¬á¡áá áºáá»á¬ážá OS threads áá»á¬ážáá±á«áºááœáẠabstraction á¡ááœáŸá¬á¡áá áºáá»á¬ážááᯠááááºáááºáá±ážáááºá abstractions áá»á¬ážáááºáá±á¬ááºááŸá¯ááŒáá·áº áá¯ááºáá±á¬ááºáá±á¬á¡áá«á áá°áá±á¬ááºáá±ážááœá²áá°áá»á¬ážááẠá¡á±á¬ááºááŒá±á¡ááá·áºáá áºáᯠááá¯á·ááá¯áẠáá áºáá¯áááºááá¯áá±á¬á¡ááá·áºááá¯á· áááºážááẠá¡ááœáá·áºá¡áááºážááᯠá áœáá·áºááœááºááá·áºáááºážáááºážááᯠá¡áá¯á¶ážááŒá¯áááºá á¡áá»á¬ážá á¯ááá±á¬á· áá«áᬠáááá¯á¡ááºáá«áá°ážá ááááºáá±á¬á· áá«áᬠááá¯áá·áºááá¯ááá¯áẠáá±áááºáá²á· ááŒá±áá±á¬ááºáá²á· áá áºááá¯á· áá¶áá«ážááœáá·áºáá¬ážáá±ááá·áº áá áºáá«áá áºáá¶ááŸá¬ ááŸá¬ážááŸá¬ážáá«ážáá«áž ááá á¹á ááœá±ááŸá¬á áááºááŸá abstraction á¡ááá·áºááŸá¬ ááŒá±ááŸááºážááá¯á·áááá²á· ááŒá¿áá¬ááᯠááŒá±ááŸááºážááá¯á· áá áºáá¯áááºážáá±á¬ áááºážáááºážááŒá áºááá¯ááºáá«áááºá .
áááááá¬áá»á¬ážá¡á¬ážááŒáá·áºá áá»áœááºá¯ááºááá¯ááá¯áááºááŸá¬ framework ááŸáá·áº third-party packages áá»á¬ážá០áá¶á·ááá¯ážáá±ážáá±á¬ application programming interfaces (APIs) áá»á¬ážá¡ááŒáẠmulti-threaded code ááŸáá·áº áááºááá¯ááºááá·áº ááŒá¿áá¬ááá¯ááºážááᯠááŸá¬ááœá±áá¬ááœáẠááá¯ážááŸááºážá á±ááá·áº software solutions áá»á¬ážá¡á¬ážáá¯á¶ážááᯠááá¯ááá¯áá«áááºá
ááŒáá¯ážáá áºáá»á±á¬ááºážááᯠá áááºáááºá
Thread class ááẠ.NET ááœáẠá¡ááŒá±áá¶á¡áá»áá¯á¶áž class ááŒá áºáááºá áááºáá±á¬ááºáá°ááẠááá¯ááºá á¬ážááŸááºááŸá áºáŠážáá²á០áá áºáŠážááᯠáááºáá¶áááº-
- ThreadStart â ááá·áºáááºáá»ááºáá»á¬ážáááŸááá«á
- ParameterizedThreadStart - á¡áá»áá¯ážá¡á á¬ážá¡áá¬ááá¹áá¯á ááá·áºáááºáá»ááºáá áºáá¯ááŒáá·áºá
ááá¯ááºá á¬ážááŸááºááẠStart method ááá¯áá±á«áºááŒá®ážáá±á¬áẠá¡áá áºáááºáá®ážáá¬ážáá±á¬ thread ááœáẠáá¯ááºáá±á¬ááºáááºááŒá áºáááºá ParametrizedThreadStart á¡áá»áá¯ážá¡á á¬ážá ááá¯ááºá á¬ážááŸááºáá áºáŠážááᯠáááºáá±á¬ááºáá°áᶠáá±ážááá¯á·áá«áá ááá¯á·áá±á¬áẠá¡áá¬ááá¹áá¯áá áºáá¯ááᯠStart áááºážáááºážááá¯á· áá±ážááá¯á·ááááºááŒá áºáááºá áááºááá·áºáá±áááá¯ááºáá¬á¡áá»ááºá¡áááºááá¯áááᯠstream ááá¯á·ááœáŸá²ááŒá±á¬ááºážááẠá€ááá¹ááá¬ážááá¯á¡ááºáá«áááºá thread áá áºáá¯ááᯠáááºáá®ážááŒááºážááẠá á»á±ážááŒá®ážáá±á¬ áá¯ááºáá±á¬ááºáá»ááºááŒá áºááŒá®áž thread ááá¯ááºááá¯ááºá áá±ážáá¶áá±á¬ á¡áá¬áá áºáá¯ááŒá áºááŒá®áž á¡áááºážáá¯á¶áž áááºážááẠstack ááœáẠmemory 1MB ááᯠááœá²áá±áá±ážáᬠOS API ááŸáá·áº á¡ááŒááºá¡ááŸááºáááºááœááºááŸá¯ ááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº áááááŒá¯ááá·áºáá«áááºá
new Thread(...).Start(...);
ThreadPool á¡áááºážááẠáá±áá°ážáááºá ááá±á¬ááá¬ážááᯠááá¯ááºá á¬ážááŒá¯áááºá .NET ááœááºá thread pool ááẠá¡ááºáá»ááºáá®áá¬á¡ááá¯ááºážáá áºáá¯ááŒá áºááŒá®ážá Microsoft á០developer áá»á¬ážááẠá¡áá»áá¯ážáá»áá¯ážáá±á¬á¡ááŒá±á¡áá±áá»á¬ážááœáẠá¡áá±á¬ááºážáá¯á¶ážá¡áá¯ááºáá¯ááºááŒá±á¬ááºážáá±áá»á¬á á±áááºá¡ááœáẠáá»á¬ážá áœá¬á¡á¬ážáá¯ááºááŒáá¯ážáááºážáá²á·ááŒáááºá
áá±áá¯áá»ááá±á¬ááá¬áž-
á¡ááá®áá±ážááŸááºážá áááºááá·áºá¡áá»áááºááŸá á áááºážááẠáá±á¬ááºáá¶ááœáẠá¡áááºá á¬ááœá²áá»á¬ážá áœá¬ááᯠáááºáá®ážáá±ážááŒá®áž áááºážááá¯á·ááᯠá¡áá¯á¶ážááŒá¯áááºá¡ááœáẠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºááŒá áºáááºá ááŒáá¯ážáá»á¬ážááᯠáááŒá¬ááááŸáá·áº á¡áá»á¬ážá¡ááŒá¬ážá¡áá¯á¶ážááŒá¯áá«áá áá±á«áºááá¯áá°áááá¯á¡ááºáá»ááºáá»á¬ážááᯠááŒáá·áºáááºážááẠáá±áá°ážáááºááẠáá»ááºááŒáá·áºáá¬áááºá áá±áá°ážáááºááœáẠá¡ááá²á·á á¬ááœá²áá»á¬áž áááŸááá±á¬á·ááá·áºá¡áá«á áááºážááẠááœá²áá»á¬ážáá²á០áá áºáá¯ááᯠááŒááºáá¬ááẠá á±á¬áá·áºááẠááá¯á·ááá¯áẠá¡áá áºáá áºáᯠáááºáá®ážáááºááŒá áºáááºá thread pool ááẠáá±ááá¯áá¯ááºáá±á¬ááºáá»ááºá¡áá»áá¯á·á¡ááœáẠáá±á¬ááºážááœááºááŒá®áž á¡ááá®áá±ážááŸááºážááááºáááºááŸá¯áá áºáá¯áá¯á¶ážááœáẠáááºáá±á¬ááºááŸá¯áá»á¬ážá¡ááŒá Ạáá¯ááºáá±á¬ááºááá·áº áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá¡ááœáẠááá·áºáá»á±á¬áºááŸá¯áááŸááá«á
áá±áá°ážáááºá០thread áá áºáá¯ááᯠá¡áá¯á¶ážááŒá¯áááºá ParametrizedThreadStart ááŸáá·áº áá°áá®áá±á¬ áááºááŸááºáá«áá±á¬ WaitCallback á¡áá»áá¯ážá¡á á¬ážá ááá¯ááºá á¬ážááŸááºáá áºáŠážááᯠáááºáá¶ááá·áº QueueUserWorkItem áááºážáááºážáá áºáᯠááŸáááŒá®áž áááºážáᶠááŒááºááœá¬ážáá±á¬ ááá·áºáááºáá»ááºááẠáá°áá®áá±á¬áá¯ááºáá±á¬ááºáá»ááºááᯠáá¯ááºáá±á¬ááºáá«áááºá
ThreadPool.QueueUserWorkItem(...);
áá°áááááºážáá±á¬ thread pool method ááᯠRegisterWaitForSingleObject ááᯠááááºááá¯á·ááŒááºážááá¯ááºáá±á¬ IO áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠá á¯á ááºážááẠá¡áá¯á¶ážááŒá¯áá«áááºá WaitHandle ááᯠáááºážáááºážááá¯á· áá±ážááá¯á·áá±á¬á¡áá« á€áááºážáááºážááá¯á· áá±ážááá¯á·áá±á¬ ááá¯ááºá á¬ážááŸááºá¡á¬áž áá±á«áºáá«áááºá
ThreadPool.RegisterWaitForSingleObject(...)
.NET ááœáẠthread timer áá áºáá¯ááŸáááŒá®áž áááºážááẠWinForms/WPF timers ááŸáá·áº ááœá²ááŒá¬ážááá·áºá¡ááœáẠáááºážáááá¯ááºááœááºáá°ááᯠáá±áá°ážáááºááŸáá¯ááºáá±á¬ thread áá áºáá¯áá±á«áºááœáẠáá±á«áºáá±á«áºáááºááŒá áºáááºá
System.Threading.Timer
BeginInvoke áááºážáááºážááᯠáá±áá°ážáááºá០ááŒáá¯ážáá áºáá¯ááá¯á· ááœááºáá»ááºáááºá¡ááœáẠááá¯ááºá á¬ážááŸááºáá áºáŠážááᯠáá±ážááá¯á·ááẠá¡ááœááºáá°ážááŒá¬ážáááºážááŒá¬ážáá±á¬áááºážáááºážáááºáž ááŸááá«áááºá
DelegateInstance.BeginInvoke
á¡áááºáá±á¬áºááŒáá« áááºážáááºážáá»á¬ážá áœá¬ááᯠáá±á«áºááá¯ááá¯ááºááá·áº áá¯ááºáá±á¬ááºáá»ááºá¡áá±á«áº á¡áá»ááºážáá»á¯á¶áž ááŒá±á¬ááŒá¬ážááá¯áááºááŸá¬ - Kernel32.dll Win32 API á០CreateThread ááŒá áºáááºá á€áá¯ááºáá±á¬ááºáá»ááºááá¯áá±á«áºááá¯ááẠextern method áá»á¬ážáááá¹ááá¬ážááŒá±á¬áá·áº áááºážáááºážáá áºáá¯ááŸááááºá ááá¯ážááá¯ážááœá¬ážááœá¬áž á¡ááœá±á¡ááŸá áºáá¯ááºá ááá¯ážááœá¬ážáá±á¬ á¥ááá¬áá áºáá¯ááœáẠá€áá²á·ááá¯á·áá±á«áºááá¯ááŸá¯ááᯠáá áºááŒáááºáᬠááŒááºáá°ážááŒá®áž áááºážááᯠáááááá»áá» áá¯ááºáá±á¬ááºáá²á·áá±á¬ á á¬áá±ážááá¬á ááŸá¯á¶á·áá±á¬áºááŸá¯ááẠáá»áœááºá¯ááºá¡ááœáẠáá»áŸáá¯á·ááŸááºáááºážááŒááºáá±áá²ááŒá áºáááºá
Kernel32.dll CreateThread
Threads áá»á¬ážááᯠááŒáá·áºááŸá¯ááŒááºážááŸáá·áº á¡ááŸá¬ážááŸá¬ááŒááºáž
áááºáááºáá®ážáá¬ážáá±á¬ á á¬ááœá²áá»á¬ážá ááŒááºáá¡ááœá²á·á¡á ááºáž á¡á áááºá¡ááá¯ááºážáá»á¬áž ááŸáá·áº .NET á á¯áá±á«ááºážá¡á¬áž Visual Studio á Threads window ááœáẠááŒáá·áºááŸá¯ááá¯ááºáá«áááºá á¡ááá®áá±ážááŸááºážááẠá¡ááŸá¬ážá¡ááœááºážááŸáá·áº Break áá¯ááºááœáẠááŸááá±áá±á¬á¡áá«ááœáẠá€áááºážááá¯ážááẠá á¬ááœá²á¡áá»ááºá¡áááºááᯠááŒááá«áááºá á€áá±áá¬ááœáẠáááºááẠthread áá áºáá¯á á®á stack á¡áááºáá»á¬ážááŸáá·áº áŠážá á¬ážáá±ážáá»á¬ážááᯠá¡áááºááŒá±á áœá¬ááŒáá·áºááŸá¯ááá¯ááºááŒá®ážá á¡ááŸá¬ážááŸá¬ááŒááºááŒááºážááᯠáá®ážááŒá¬áž thread áá áºáá¯ááá¯á· ááŒá±á¬ááºážááá¯ááºáááºá Thread class á áŠážá á¬ážáá±áž ááá¯ááºááá¯ááºááŸá¯ááᯠá¡áá¯á¶ážááŒá¯á thread áá»á¬ážááŒá¬ážááœáẠáááá¯áááºáá¬á¡áá»áááºááᯠááá¯ááºážááŒá¬ážááá·áºá¡áá« OC ááŸáá·áº CLR á០á¡ááŒá¶ááŒá¯áá»ááºá¡ááŒá Ạáááºáá¶ááá·áº thread áá áºáá¯á áŠážá á¬ážáá±ážááᯠáááºáááºááŸááºááá¯ááºáá«áááºá
Task Parallel Library
Task Parallel Library (TPL) ááᯠ.NET 4.0 ááœáẠááááºáááºáá²á·áááºá ááá¯á¡áá« áááºážááẠá á¶ááŸá¯ááºážááŸáá·áº áá»áááºááá¯ááºáá¯ááºáá±á¬ááºááŒááºážá¡ááœáẠá¡ááááááááá¬ááŒá áºáááºá á¡áá±á¬ááºážáááºážáááºážááᯠá¡áá¯á¶ážááŒá¯ááá·áº áááºááá·áºáá¯ááºááá¯áááᯠá¡ááœá±á¡ááŸá áºá¡ááŒá ẠáááºááŸááºáááºá TPL á á¡ááŒá±áá¶áá°áá áºááẠSystem.Threading.Tasks namespace á០Task class ááŒá áºáááºá á¡áá¯ááºáá áºáá¯ááẠá¡ááá¯ááºážáá áºáá¯á¡áá±á«áºááœáẠá áááºáá°ážáááºááŸá¯áá áºáá¯ááŒá áºáááºá C# áá¬áá¬á áá¬ážá áá¬ážááŸááºážá¡áá áºááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠTasks - async/ait operators áá»á¬ážááŸáá·áº áá¯ááºáá±á¬ááºááẠá¡á¶áááºááœááºáá» áááºážáááºážáá áºáᯠáááŸááá²á·áá«áááºá á€ááá±á¬ááá¬ážáá»á¬ážááẠááá¯ážááŸááºážááŒá®áž áááºáá°áá»ááá·áºáá¯ááºááᯠááá¯ážááŸááºážááŒá®áž áááºáá°áá»á á±ááá·áºá¡ááá¯ááºáž á¡ááŒáá¯ááºá¡ááá¯ááºáá±ážáá¬ážááá¯ááºá á±áááºá áááºážááẠthread áá»á¬ážáá¡ááœááºážááá¯ááºážáá¯ááºáá±á¬ááºááŸá¯áá»á¬ážááᯠáá¬ážááááºáá±ážáá°áá»á¬ážá¡ááœáẠáááºážááá¯á·ááá¯á¡áá¯á¶ážááŒá¯ááá·áºá¡ááºááºáá®áá±ážááŸááºážáá»á¬ážá ááŒá¬ááŒáá·áºá áœá¬áá¯ááºáá±á¬ááºááá·áºá¡áá«ááœáẠá¡á±ážáá²ááŒááºážáááŸáááá·áºá¡ááºááºáá®áá±ážááŸááºážáá»á¬ážááᯠáá±ážáá¬ážáááºááŒá áºááá¯ááºá á±áá²á·áááºá async/await ááá¯á¡áá¯á¶ážááŒá¯ááŒááºážááẠáá±á¬ááºážáá«ážáá áºáá¯áẠááá¯á·ááá¯áẠá¡áá»á¬ážá¡ááŒá¬ážá¡ááœáẠáá±á«ááºážá ááºáá áºáá¯ááŒá áºáááºá ááá¯á·áá±á¬áº á á¬ááŒá±á¬ááºážá¡áááºážáááºááŒáá·áº áááºážáá¡ááŸá áºáá¬áááᯠááá°ááẠááŒáá¯ážá á¬ážáá«áááºá
- async ááẠTask ááá¯á· ááŒááºáá±ážááŒááºáž ááá¯á·ááá¯áẠáá»ááºááŒááºááœá¬ážáá±á¬ áááºážáááºážá ááœááºážáá¶ááŸá¯áá áºáá¯ááŒá áºáááºá
- á á±á¬áá·áºááá¯ááºážááŒááºážááẠááááºááá¯á·ááŒááºážááá¯ááºáá±á¬ Task á á±á¬áá·áºááá¯ááºážáá±áá±á¬ á¡á±á¬áºááá±áá¬áá áºáá¯ááŒá áºáááºá
áá áºáááº- á á±á¬áá·áºáá»áŸá±á¬áºáá±áá±á¬ á¡á±á¬áºááá±áá¬ááẠáá±áá¯áá»á¡ááŒá±á¡áá±ááœáẠ(ááŒáœááºážáá»ááºáá»á¬ážááŸááá«áááº) ááẠáááºááŸááá¯ááºáá±á¬ááºááŸá¯ááá»ááºááŸá±á¬ááºááŸá¯ááᯠáááºáá¶áá¯ááºááŒááºáááºááŒá áºááŒá®ážá Task ááẠáááºážááá¯ááºáá±á¬ááºááŸá¯ááᯠá¡ááŒá®ážáááºááá·áºá¡áá«á ááŸáá·áº thread (á¡ááŸááºá¡á¬ážááŒáá·áº á áá¬ážá ááºááá¯ááá»áŸáẠááá¯ááŸááºáááºááŒá áºáááºá áá«áá±ááá·áº áá±á¬ááºááá¯ááºážááŸá¬ áá±á¬ááºáááº) áááºážáááºážááᯠáááºáááºáá¯ááºáá±á¬ááºááœá¬ážááŸá¬ááŒá áºáá«áááºá .NET á¡ááœááºážááœááºá áá±ážáá¬ážáá¬ážáá±á¬áááºážáááºážááẠstate machine áá áºáá¯ááŒá áºááá·áº class áá áºáá¯áá¯á¶ážá¡ááŒá áºááá¯á· ááŒá±á¬ááºážáá²ááœá¬ážáá±á¬á¡áá«ááœáẠá€ááá¹ááá¬ážá¡á¬áž áá®ážááŒá¬ážá¡ááá¯ááºážáá»á¬ážá¡ááá¯áẠáá¯ááºáá±á¬ááºááá¯ááºááẠá á áááºáá«áááºá á¬ážáá°áááºáá°áááᯠasynÑ/awaitá compiler ááŸáá·áº Compiler Generated Code ááœáá·áºáá¬ážáá±á¬ JetBrains dotPeek ááᯠá¡áá¯á¶ážááŒá¯á ááá¯ážááŸááºážáá±á¬áá¯ááºáá áºáá¯áá¯ááᯠáá±ážáá¬ážááá¯ááºáááºá
Task á áááºááŒááºážááŸáá·áº á¡áá¯á¶ážááŒá¯ááŒááºážá¡ááœáẠááœá±ážáá»ááºá áá¬áá»á¬ážááᯠááŒáá·áºááŒáá«á áá¯á·á á¡á±á¬ááºáá±á¬áºááŒáá« áá¯ááºááá°áá¬ááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡áá¯á¶ážááááºáá±á¬ á¡áá¯ááºá¡áá áºáá áºáá¯ááᯠáááºáá®ážááẠ(ááŒáá¯ážá á¡áááºáá»ááẠ(ááááá)) ááá¯á·áá±á¬áº áááºááœá±á·ááááœáẠáááºážááẠááŸá¯ááºááœá±ážáá±á¬ 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
}
Task áá áºáá¯ááᯠááœá±ážáá»ááºá áá¬áá»á¬ážá áœá¬ááŒáá·áº áááºáá®ážáá¬ážáááº-
- LongRunning ááẠáá¯ááºáááºážááᯠáá»ááºááŒááºá áœá¬ ááŒá®ážááŒá±á¬ááºáááá·áºáááºááá¯ááºááŒá±á¬ááºáž á¡ááááºá¡ááŒáœááºááá¯ááá¯áááºá ááá¯ááá¯áááºááŸá¬ áááºážááẠáá±áááºá០áá»ááºáá»áŸááºáá áºáá¯ááᯠááá°áá² á¡ááŒá¬ážáá°áá»á¬ážááᯠáááááá¯ááºá á±áááºá¡ááœáẠá€áá¯ááºáááºážá¡ááœáẠáá®ážááŒá¬ážáá áºáá¯ááᯠáááºáá®ážááŒááºážáááºááŒá áºáááºá
- AttachedToParent - áá¯ááºáá±á¬ááºá áá¬áá»á¬ážááᯠá¡áááºáááºážáá»áá» á á®á ááºááá¯ááºáá«áááºá á€ááœá±ážáá»ááºááŸá¯ááᯠá¡áá¯á¶ážááŒá¯áá«áá Task ááẠáááºážááá¯ááºááá¯áẠááŒá®ážááŒá±á¬ááºááŒá®áž áááºážáááá±ážáá»á¬ážááᯠááœááºáá»ááºááẠá á±á¬áá·áºááá¯ááºážáá±ááá·áº á¡ááŒá±á¡áá±ááœáẠááŸááá±ááá¯ááºáááºá
- PreferFairness - ááá¯áááºááŸá¬ áá±á¬ááºááá¯ááºážááœáẠáá±ážááá¯á·ááŒááºážáááŒá¯áá® á á±á¬á á±á¬á áá±ážááá¯á·áá¬ážáá±á¬ Tasks áá»á¬ážááᯠáá¯ááºáá±á¬ááºááŒááºážááẠááá¯áá±á¬ááºážáááºáᯠááá¯ááá¯áááºá ááá¯á·áá±á¬áº áááºážááẠá¡ááŒá¶ááŒá¯áá»ááºáá áºáá¯áá¬ááŒá áºááŒá®áž ááááºáá»á¬ážááᯠá¡á¬áááá¶ááá¯ááºáá«á
áááºážáááºážááá¯á· ááŒááºááœá¬ážáá±á¬ áá¯ááá ááá·áºáááºáá»ááºááŸá¬ CancellationToken ááŒá áºáááºá á áááºááŒá®ážáá±á¬áẠáá¯ááºáá±á¬ááºáá»ááºáá áºáá¯á¡á¬áž áá»ááºááááºážááŒááºážá¡á¬áž ááŸááºáááºá áœá¬ááá¯ááºááœááºáááºá áá¯ááºáá±á¬ááºáá±ááá·áºáá¯ááºááẠCancellationToken á¡ááŒá±á¡áá±á¡ááœáẠá á áºáá±ážááŸá¯áá»á¬ážááŸáá·áº ááŒáá·áºáá±ááááºááŒá áºáááºá á á áºáá±ážááŸá¯áá»á¬ážáááŸááá«áá CancellationTokenSource á¡áá¬ááá¹áá¯ááŸá CancellationTokenSource áá¯áá±á«áºáá±á¬ Cancel áááºážáááºážááẠTask ááá¯ááºáá±á¬ááºááŸá¯ááᯠáá áááºáá®ááœááºáᬠáááºááá·áºááá¯ááºáááºááŒá áºáááºá
áá±á¬ááºáá¯á¶ážáá±á¬ááºááẠTaskScheduler á¡áá»áá¯ážá¡á á¬ážá á¡áá»áááºááá¬ážááœá²ááá·áºá¡áá¬áá áºáá¯ááŒá áºáááºá á€á¡áááºážááŸáá·áº áááºážááá¬ážá ááºááŒá±ážáááºáá»á¬ážááẠá á¬ááœá²áá»á¬ážáá áºáá»áŸá±á¬áẠTasks áá»á¬ážááᯠááŒáá·áºáá±ááŒááºážá¡ááœáẠááá¬áá»á°áá¬áá»á¬ážááᯠááááºážáá»á¯ááºááẠáá®ááá¯ááºážáá¯ááºáá¬ážááŒá®ážá áá¯á¶ááŸááºá¡á¬ážááŒáá·áº Task ááᯠáá±áá°ážáááºá០áá»áááºážááœá²áá áºáá¯áá±á«áºááœáẠáá¯ááºáá±á¬ááºáááºááŒá áºáááºá
á á±á¬áá·áºááá¯ááºážáá±áá±á¬ á¡á±á¬áºááá±áá¬á¡á¬áž áááºáá®ážáá¬ážáá±á¬ Task ááá¯á· áááºáá±á¬ááºáááºá ááá¯ááá¯áááºááŸá¬ áááºážáá±á¬ááºááœááºáá±ážáá¬ážáá±á¬áá¯ááºááᯠá á±á¬áá·áºááŒáá¯áá±ááá·áºáá¯ááºáá²á·ááá¯á· áá°áá®áá±á¬á¡ááŒá±á¬ááºážá¡áᬠ(áááŒá¬ááááá¯áááᯠáááºážááẠáá°áá®áá±á¬á¡ááŒá±á¬ááºážá¡áá¬ááœááº) áá¯ááºáá±á¬ááºááœá¬ážáááºááŒá áºáááºá
áááºážáááºážááᯠasync void á¡ááŒá Ạá¡ááŸááºá¡áá¬ážááŒá¯áá¬ážááŒá®ážá ááá¯ááá¯áááºááŸá¬ áááºážááẠá á±á¬áá·áºáá±áá±á¬ á¡á±á¬áºááá±áá¬á¡á¬áž á¡áá¯á¶ážááŒá¯ááá¯ááºáá±á¬áºáááºáž áá±á«áºááá¯ááŸá¯áá¯ááºááẠáá¯ááºáá±á¬ááºááŸá¯á¡ááœáẠá á±á¬áá·áºááá¯ááºážááá¯ááºáááºááá¯ááºáá«á ááá¯ááá¯á·áá±á¬á¡ááºá¹áá«áááºááá¯á¡ááºáá«áá ááá¯á·áá±á¬ááºáááºážáááºážááẠTask ááá¯ááŒááºááá«áááºá async áá»ááºááŒááºááŒá±á¬ááºáž á¡ááŸááºá¡áá¬ážááŒá¯ááá·áºáááºážáááºážáá»á¬ážááẠá¡ááœááºá¡áá¯á¶ážáá»á¬ážáááº- á ááºážáááºážá¡áá áááºážááá¯á·ááẠá¡ááŒá áºá¡áá»ááºááᯠááá¯ááºááœááºááŒá±ááŸááºážáá°áá»á¬áž ááá¯á·ááá¯áẠáá®ážááŸáá·áºáá±á·áá±á¬áááá¬áááᯠáá¯ááºáá±á¬ááºááá·áº á¡ááŒá¬ážáááºážáááºážáá»á¬ážááŒá áºáááºá á¡áááºá áááºááẠáá¯ááºáá±á¬ááºááŸá¯ááŒá®ážáá¯á¶ážááá·áºááá¯ááºá¡á±á¬áẠá á±á¬áá·áºááá¯ááºážááẠá¡ááœáá·áºá¡áá±ážááᯠáá±ážáá¯á¶áá¬áá ááááºááá¯áááºáž ááŒááºáá±ážááá¯áá«á Task ááᯠá¡áá¯á¶ážááŒá¯ááẠááá¯á¡ááºáá«áááºá
StartNew method ááŸááŒááºáá¬áá±á¬ Task ááœááºá¡ááŒáẠá¡ááŒá¬ážáááºááá·áºá¡áá¬ááœááºáááᯠfalse parameter ááŒáá·áº ConfigureAwait method ááá¯áá±á«áºááá¯ááá¯ááºáááºá ááá¯á·áá±á¬áẠá á±á¬áá·áºáá»áŸá±á¬áºááŒá®ážáá±á¬áẠexecution ááẠcaptured context ááœááºáááºáááºáá¯ááºáá±á¬ááºáááºááá¯ááºáá±á¬áºáááºáž ááááºáááá¯áá áºáá¯áá±á«áºááœááºááŒá áºáááºá á á±á¬áá·áºááá¯ááºážááŒá®ážáá±á¬áẠáá¯ááºá¡ááœáẠáá¯ááºáá±á¬ááºááŸá¯á¡ááŒá±á¬ááºážá¡áá¬ááẠá¡áá±ážáááŒá®ážááá·áºá¡áá« áááºážááᯠá¡ááŒá²áááºážáá¯ááºáá±á¬ááºááá·áºáááºá áá áºáá»á áºááá¯ááºááœááºáá¯ááºááá¯ážáá¬ážáá±á¬áá¯ááºááá¯áá±ážáá±á¬á¡áá«áááºážááẠMS ááŸá¡ááŒá¶ááŒá¯áá»ááºáááºážááŒá áºáááºá
Task áá áºáá¯ááŒá®ážááŒá±á¬ááºá¡á±á¬áẠáááºááá¯á á±á¬áá·áºáááá²ááá¯áá²á·á¡ááŒá±á¬ááºáž áááºážáááºážáá±á¬áẠáááºááŒá±á¬ááŒáá·áºáá¡á±á¬ááºá á¡á±á¬ááºááœááºáá±á¬áºááŒáá¬ážáá±á¬ áá¯ááºáááá°áá¬áá áºáá¯ááŒá áºááŒá®ážá áá»áŸá±á¬áºááá·áºááŒááºážá¡á¬áž á¡ááŒá±á¡áá±á¡á áá±á¬ááºážááœááºá áœá¬áá¯ááºáá±á¬ááºááá·áºá¡áá«ááŸáá·áº á¡ááŒá±á¡áá±á¡á áá¶á·áá»ááºážá áœá¬áá¯ááºáá±á¬ááºááá·áºá¡áá«ááœáẠááŸááºáá»ááºáá»á¬ážááŸáá·áºá¡áá° á¡á±á¬ááºááœááºáá±á¬áºááŒáá¬ážáááºá
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
}
áááááá°áá¬ááœááºá áá»áœááºá¯ááºááá¯á·ááẠáá±á«áºááá¯ááŸá¯á¡ááºááááºááᯠáááááºááá¯á·áá² Task ááŒá®ážááŒá±á¬ááºááẠá á±á¬áá·áºáá»áŸá±á¬áºáá±áá«áááºá áááºážááŸáááŒá®ážáá¬ážááŸáᬠááááºááᯠáá¯ááºáá±á¬ááºááŒááºážááá¯á· ááŒááºááœá¬ážáá«áááºá ááá¯á¡áá»áááºá¡áá áá¯ááºážáá±á«áºááá¯ááŸá¯áá»ááºáá»áŸááºááᯠáááºážáááá¯ááºááá¯ááºá ááºáá á¹á ááºážáá»á¬ážááá¯á· áá»ááºáá¬ážáá²á·áá«áááºá
áá¯áááááœá±ážáá»ááºááŸá¯ááœááºá áááºážáááºážáááááºááᯠáááœááºáá»ááºááá»ááºáž áá¯ááºážáá±á«áºááá¯ááŸá¯ááá¯ááºážááᯠáá»áœááºá¯ááºááá¯á· ááááºááá¯á·áá¬ážáááºá ááá¯ážááŸááºážáá±á¬ áá»ááºážááááŸá¯ááŸáá·áºá¡áá° áááá¯ááááºá á¡ááá¯ážáááºá¡áááºážá¡ááŒá áºááŒá áºááá·áº áá»ááºáá»áŸááºáá áºáá¯ááᯠáá»áœááºá¯ááºááá¯á· ááááºážááá¯ááºáá¬ážááŒááºážááŒá±á¬áá·áºáá¬áá áá»áœááºá¯ááºááá¯á·áá±á«áºááá¯áá±á¬ áááºážáááºážááá¯ááºááœáẠá¡ááá·áºááŸááá±áá«áá áá±á«ááºážá ááºááœá²á·á ááºážááŸá¯ááá¯ááºáᬠá¡ááŒá±á¬ááºážá¡áá¬ááẠáá±á«áºááá¯ááŒá®ážáá±á¬áẠáá±á«áºááá¯ááŸá¯ááœá²ááá¯á· ááŒááºááœá¬ážááẠááá¯á¡ááºáá±á¬ááŒá±á¬áá·áºá á á±á¬áá·áºáá«á ááá¯á·áá±á¬áẠáá»áœááºá¯ááºááá¯á·ááẠááá±áá±á¬áá±á¬á·ááºáá áºáá¯ááᯠáááŸááááá·áºáááº- áá±á«áºááá¯ááŸá¯áá»ááºáá»áŸááºááẠá¡ááŒáá¯ááºá¡ááá¯ááºááœááºáá»ááºáááá·áºáááºážáááºážáááááºááᯠá á±á¬áá·áºáá»áŸá±á¬áºáá±áᬠáá±á«áºááá¯ááŸá¯ááœá²ááœáẠáááºáááºáá¯ááºáá±á¬ááºááẠá¡áá»ááºážááŸá®ážááŒáá¯ážá á¬ážáá±áá«áááºá
á€áá»ááºážáááºááŸá¯ááá±á¬ááºáááºá¡á¬ážáááºážáá»ááºááŸá¬ ááŸá¯ááºááœá±ážáá±á¬ á¡ááŸá¬ážá¡ááœááºážáá»á¬ážááᯠááá¯ááºááœááºááŒááºážáááºááŒá áºáááºá á¡ááŒá áºááŸááºááŸá¬ async/await ááá¯á¡áá¯á¶ážááŒá¯áá±á¬á¡áá«ááœáẠasynchronous áá¯ááºá¡ááŸá¬ážáá»á¬ážááẠááá¯ááºááœááºáááºá¡ááœááºááœááºáá°ááẠ- áááºážááá¯á·ááẠáá¯ááºááᯠsynchronous ááŒá áºááá²á·ááá¯á· á¡áá¬ážáá°ááŒá¯áá°áááºá Task áá áºáá¯ááœáẠsynchronous wait exorcism ááᯠá¡áá¯á¶ážááŒá¯áá«á áá°áááºážááŒáœááºážáá»ááºááẠAggregateException á¡ááŒá áºááá¯á· ááŒá±á¬ááºážáá²ááœá¬ážáá«áááºá ááŒáœááºážáá»ááºá¡á¬áž ááá¯ááºááœááºáááºá áááºááẠInnerException á¡áá»áá¯ážá¡á á¬ážááᯠá á áºáá±ážááŒá®áž C# ááá¹áá¬ááœáẠááá¯ááá¯áááºážááŸá®ážáá±á¬ áááºážáá¯á¶ážáá»á¬ážá ááœááºážáááºá¡á á¬áž áááºážááœááºáá áºáá¯á¡ááœááºážá áááºááá¯ááºááá¯áẠááœááºážáááºáá áºáá¯ááᯠáá±ážáá« ááá¯á·ááá¯áẠáááºáá±á¬ááºááá·áºá¡áá« áááºážááŒááºážááᯠá¡áá¯á¶ážááŒá¯áá«á
ááááááŸáá·áº áá±á¬ááºáá¯á¶ážááá°áá¬áá»á¬ážááẠáá°áá®áá±á¬á¡ááŒá±á¬ááºážááŒáá»ááºááŒá±á¬áá·áº ááá±á¬ááºážááŒá±á¬ááºáž á¡ááŸááºá¡áá¬ážááŒá¯ááŒááŒá®áž áá°áá®áá±á¬ááŒá¿áá¬áá»á¬áž áá«áááºáááºá
WhenAny ááŸáá·áº WhenAll method ááẠTasks á¡ááœá²á·ááᯠá á±á¬áá·áºááá¯ááºážáááºá¡ááœáẠá¡ááœááºá¡áááºááŒá±áááºá áááºážááá¯á·ááẠTasks áá áºá á¯ááᯠáá áºááœá²á·á¡ááŒá Ạá á¯á ááºážáá¬ážáᬠáááºážááá¯á·ááẠá¡ááœá²á·á០Task áá áºáá¯ááᯠá áááºáá¯ááºáá±á¬ááºááá·áºá¡áá« ááá¯á·ááá¯áẠáááºážááá¯á·á¡á¬ážáá¯á¶áž áááºážááá¯á·á execution ááŒá®ážááœá¬ážáá±á¬á¡áá«ááœááºááẠá¡áá¯ááºáá¯ááºáááºááŒá áºáááºá
ááá¯ááºážáá»á¬ážáááºááá·áºááŒááºážá
á¡ááŒá±á¬ááºážá¡áá»áá¯ážáá»áá¯ážááŒá±á¬áá·áº á á®ážáááºážááŸá¯ááᯠáááºááá·áºááẠááá¯á¡ááºááá¯ááºáááºá áá®ááá¯áá¯ááºááá¯á· áááºážáááºážáá»á¬ážá áœá¬ááŸááá«áááºá Thread class ááœáẠááá·áºáá»á±á¬áºáá±á¬ á¡áááºáá±ážáá¬ážáá±á¬ áááºážáááºážááŸá áºáá¯ááŸááááºá áá»ááºááááºáž О ááŒá¬ážááŒááº. ááááá áºáá»áá¯ážááᯠá¡áá¯á¶ážááŒá¯ááẠá¡ááœááºá¡áááºáž áá¡ááŒá¶ááŒá¯áá¬ážáá±á¬ááŒá±á¬áá·áº ááŒá áºáááºá ááŒá¯á¶áá¬á¡ááá¯ááºá¡ááá·áºáá áºáá¯áá¯ááœáẠáááºážááá¯áá±á«áºááá¯ááŒá®ážáá±á¬ááºá áááºááá·áºááœáŸááºááŒá¬ážáá»ááºááá¯áááᯠáá¯ááºáá±á¬ááºáá±á ááºá¡ááœááºáž ááŒáœááºážáá»ááºáá áºáá¯á¡á¬áž áá»áœááºážáá»ááºáá¬ážáááºááŒá áºáááºá ThreadAbortedException. integer variable áá áºáá¯áá¯ááᯠááá¯ážáá¬áá²á·á¡áá« áá®ááá¯ááŒáœááºážáá»ááºáá áºáá¯ááᯠááœáŸááºáá»ááá¯á· áááºááá»áŸá±á¬áºááá·áºáá¬ážáá°ážáá¬ážá áá®áááºážááá¯áá¯á¶ážáá²á·á¡áá« áá«á áááá·áºá¡ááŒá±á¡áá±áá«á á¡áááºá áááºááẠCLR ááᯠáá¯ááºá á¡áá»áá¯á·áá±á¬ ááá¹ááá áºáá¯ááœáẠááá¯ááá¯á·áá±á¬ááŒáœááºážáá»ááºáá áºáᯠáááºáá®ážááŒááºážá០áá¬ááœááºááẠááá¯á¡ááºáá«áá áááºááẠáááºážááᯠáá±á«áºááá¯ááŸá¯áá»á¬ážááœáẠááá·áºááœááºážááá¯ááºááẠThread.BeginCriticalRegion, Thread.EndCriticalRegion. áá±á¬ááºáá¯á¶áž ááá±á¬ááºáá áºáá¯ááœáẠáá±ážáá¬ážáá±á¬ áááºááá·áºáá¯ááºáááᯠáá±á«áºááá¯ááŸá¯áá»á¬ážááœáẠááá·áºááœááºážáá¬ážáááºá á€á¡ááŒá±á¬ááºážááŒá±á¬áá·áºá framework code ááááºáá²áá±á¬áá±áá¬ááœáẠá¡áá»ááºážááŸá®ážááŒáá¯ážá á¬ážááŒááºážááŒáá·áº blocks áá»á¬ážááᯠááŸá¬ááœá±á·ááá¯ááºáá±á¬áºáááºáž áá±á¬ááºáá¯á¶ážááœáẠááá¬ááá¯ááºáá«á Microsoft ááẠá€áááºážáááºážááᯠ.net core ááœáẠáááá·áºááœááºážáá¬ážáá±á¬ááŒá±á¬áá·áº á€áááºážáááºážááᯠá¡ááœááºá¡áááºáž áá¬ážáááºá
Interrupt method ááẠááá¯á ááá·áºááŸááºážááá¯ááºááẠá ááŒáœááºážáá»ááºá¡áá±ááŒáá·áº áááºážááẠááŒáá¯ážááᯠááŸá±á¬áá·áºááŸááºááá¯ááºáááºá ThreadInterruptedException áá»ááºáá»áŸááºááẠá á±á¬áá·áºááá¯ááºážáá±ááá·áº á¡ááŒá±á¡áá±ááœááºáᬠááá¯á¡áá»áááºáá»á¬ážá¡ááœááºážáᬠááŒá áºáááºá WaitHandleá áá±á¬á·ááºáá»ááŒááºáž ááá¯á·ááá¯áẠThread.Sleep ááá¯áá±á«áºááá¯ááŒá®ážáá±á¬áẠá á±á¬áá·áºááá¯ááºážáá±á ááºááœáẠáááºážááẠá€á¡ááŒá±á¡áá±ááá¯á· áááºáá±á¬ááºáááºá
á¡áááºááœááºáá±á¬áºááŒáá¬ážáá±á¬ ááœá±ážáá»ááºá áá¬ááŸá áºáá¯áá¯á¶ážááẠáááºážááá¯á·á ááŸááºážáááááŒááºážááŒá±á¬áá·áº ááá¯ážááœá¬ážáá«áááºá ááŒá±ááŸááºážáááºážááŸá¬ ááœá²á·á ááºážáá¯á¶ááᯠá¡áá¯á¶ážááŒá¯áááºááŒá áºáááºá CancellationToken ááŸáá·áºá¡áááºáž CancellationToken á¡áááºážá¡ááŒá áº. á¡áááá¡áá»ááºááŸá¬ á€á¡áá¬ááŒá áºáááº- CancellationTokenSource á¡áááºážáá¥ááá¬áá áºáá¯ááᯠáááºáá®ážáá¬ážááŒá®áž áááºážááá¯ááá¯ááºááá¯ááºáá°áá¬áá»áŸáẠáááºážáááºážááá¯áá±á«áºááá¯ááŒááºážááŒáá·áº áá¯ááºáá±á¬ááºáá»ááºááᯠáááºááá·áºááá¯ááºáááºá Cancel. CancellationToken ááá¯áᬠáá¯ááºáá±á¬ááºáá»ááºááá¯ááºááá¯áẠáá±ážááá¯á·áááºá CancellationToken ááá¯ááºááŸááºáá»á¬ážááẠáá¯ááºáá±á¬ááºáá»ááºááᯠáááºážááá¯á·ááá¯ááºááá¯áẠááááºáá»ááºááá¯ááºáá±á¬áºáááºáž áá¯ááºáá±á¬ááºáá»ááºááᯠáá»ááºááááºážááá¯ááºááŒááºáž ááŸááááŸáááá¯áᬠá á áºáá±ážááá¯ááºáá«áááºá á€á¡ááœáẠBoolean ááá¯ááºááá¯ááºááŸá¯áá áºáá¯ááŸááááºá áááºáá»ááºááẠáá±á¬ááºážááá¯áá¬ážáááºá ááŸáá·áºáááºážáááºáž ThrowIfCancel áá±á¬ááºážááá¯áá¬ážáááºá. áá±á¬ááºááá¯ááºážááŸá¬ ááŒáœááºážáá»ááºáá áºáᯠáá»ááá¯ááºáááá·áºáááºá TaskCancelledException CancellationToken instance ááœáẠCancel method ááᯠáá±á«áºáá«áá ááŒá®ážáá±á¬á· áá«á áá»áœááºáá±á¬áºáá¯á¶ážááá¯á· á¡ááŒá¶ááŒá¯áá¬ážáá²á· áááºážáááºážáá«á ááŒáœááºážáá»ááºáá¯ááºáá±á¬ááºáá»ááºááᯠáááºááá·áºá¡áá»ááºááœáẠáá»ááºááááºážááá¯ááºáááºááᯠá¡ááŒáá·áºá¡áááááºážáá»á¯ááºááá¯ááºááŒááºážááŒáá·áº áááºážááẠááááºááœá±ážáá»ááºááŸá¯áá»á¬ážááẠááá¯ážáááºááŸá¯áá áºáá¯ááŒá áºáááºá
thread áá áºáá¯ááᯠáááºááá·áºááẠá¡áááºá ááºáá¯á¶áž ááœá±ážáá»ááºááŸá¯ááŸá¬ Win32 API TerminateThread áá¯ááºáá±á¬ááºáá»ááºááᯠáá±á«áºááŒááºážááŒá áºáááºá á€áá¯ááºáá±á¬ááºáá»ááºááá¯áá±á«áºááá¯ááŒá®ážáá±á¬áẠCLR áá¡ááŒá¯á¡áá°ááẠááá·áºááŸááºážááááá±á MSDN ááœáẠá€áá¯ááºáá±á¬ááºáá»ááºá¡ááŒá±á¬ááºáž á¡á±á¬ááºáá«á¡ááá¯ááºáž áá±ážáá¬ážáá¬ážáááºá âTerminateThread ááẠá¡ááœááºááá¯ážááœá¬ážáá±á¬ ááá á¹á áá»á¬ážááœááºáᬠá¡áá¯á¶ážááŒá¯ááá·áºááá·áº á¡áá¹ááá¬ááºááŸááá±á¬ áá¯ááºáá±á¬ááºáá»ááºáá áºáá¯ááŒá áºáááºá â
FromAsync áááºážáááºážááᯠá¡áá¯á¶ážááŒá¯á á¡ááœá±á¡ááŸá ẠAPI ááᯠTask Based á¡ááŒá áºááá¯á· ááŒá±á¬ááºážáá²ááŒááºážá
Tasks áá»á¬ážááᯠááááºáááºááŒá®áž developer á¡áá»á¬ážá á¯á¡ááœáẠááááºááááºááááºáááẠááááºááá·áºá áá¬ááŒá áºá á±ááẠáááºááá¯ááºážááá¯ááºááŒá®ážáá±á¬áẠá áááºáá²á·áá±á¬ ááá±á¬áá»ááºáá áºáá¯ááœáẠáááºáá¯ááºáá±á¬ááºááá¯ááºáá±á¬ááºá¡á±á¬áẠáá¶áá±á¬ááºážáá«áá ááá¯á·áá±á¬ááºááœáẠáááºááẠááŒááºáá¡ááœá²á·á¡á ááºážááŸáá·áº ááá·áºá¡ááœá²á·á¡á¬áž API á¡áá±á¬ááºážáá»á¬ážá áœá¬ááᯠááá¯ááºááœááºááŒá±ááŸááºážááẠáááá¯á¡ááºáá«á á¡áááºáá¯ááºážá ááŸáááºá ááºáááºá áá¶áá±á¬ááºážá áœá¬áá²á .NET Framework á¡ááœá²á·ááẠáá»áœááºá¯ááºááá¯á·ááᯠááá¯á áá¯ááºááẠáááºááŸááºážáá»ááºááŒá áºáá±á¬ááºážááŒá áºááá¯ááºáá±á¬áºáááºážá áá»áœááºá¯ááºááá¯á·ááᯠááá¯á áá¯ááºáá²á·áááºá ááŒá áºááá¯ááºáááºá¡ááá¯ááºážá .NET ááœáẠáá±á¬ááºážááœááºážáá±á¬ asynchronous áááá¯ááááºážáááºážááŒáá·áº áá±ážáá¬ážáá¬ážáá±á¬ áá¯ááºá¡áá áºááᯠá¡áá áºááá¯á· áá»ááºážáááºáá¬ááœáẠááá¬áá»ááºáá² ááŒá±á¬ááºážáá²ááá¯ááºáá±á¬ áááááá¬áá»á¬ážá áœá¬ááŸááááºá áááºážááá¯á·áá²ááŸáá áºáá¯ááŸá¬ TaskFactory á FromAsync áááºážáááºážááŒá áºáááºá á¡á±á¬ááºáá±á¬áºááŒáá« áá¯ááºááá°áá¬ááœááºá á€áááºážáááºážááᯠá¡áá¯á¶ážááŒá¯á Task áá áºáá¯ááœáẠWebRequest á¡áááºážá async áááºážáááºážáá±á¬ááºážááᯠááŒá¯á¶áá¯á¶áááá«áááºá
object state = null;
WebRequest wr = WebRequest.CreateHttp("http://github.com");
await Task.Factory.FromAsync(
wr.BeginGetResponse,
we.EndGetResponse
);
áááºážááẠááá°áá¬áá áºáá¯áá¬ááŒá áºááŒá®áž áááºááẠbuilt-in á¡áá»áá¯ážá¡á á¬ážáá»á¬ážááŒáá·áº áááºážááá¯áá¯ááºáá±á¬ááºááẠáááŒá áºááá¯ááºáá±á¬áºáááºáž áááºááá·áºááá±á¬áá»ááºáá±á¬ááºážááẠáááºážááá¯áááºáá¶áááŸáááá·áº IAsyncResult ááŸáá·áº EndDoSomething áááºážáááºážáá»á¬ážááᯠááŒááºáá±ážááá·áº BeginDoSomething áááºážáááºážáá»á¬ážááŒáá·áº ááá¯ážááŸááºážáá«áááºá
TaskCompletionSource á¡áááºážááᯠá¡áá¯á¶ážááŒá¯á á¡ááœá±á¡ááŸá ẠAPI ááᯠTask Based ááá¯á· ááŒá±á¬ááºážáá«á
áá±á¬ááºáááºá¡áá±ážááŒá®ážáá²á· áááááá¬áá áºáá¯ááá±á¬á· á¡áááºážá¡á á¬ážáá«á TaskCompletionSource. áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážá áááºááœááºáá»ááºááŸáá·áº áá¯ááºáá±á¬ááºááŸá¯áááá¬áá¡áá áááºážááẠá¡áááºááœááºáá±ážáá¬ážáá²á·ááá·áº ThreadPool á¡áááºážá RegisterWaitForSingleObject áááºážáááºážááᯠá¡áááºážáááºáááááá±áá±áááºá á€á¡áááºážá¡á á¬ážááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áºá Tasks ááœáẠá¡áá±á¬ááºážáá»á¬ážááᯠá¡ááœááºááá°ááŸáá·áº á¡áááºááŒá±á áœá¬ ááááºážááá¯ááºáááºá
á€áááºááœááºáá»ááºáá»á¬ážá¡ááœáẠáááºááœááºáá¬ážáá±á¬ TaskFactory á¡áááºážá FromAsync áááºážáááºážááᯠáá»áœááºá¯ááºááŒá±á¬áá²á·ááŒá®ážááŒá®áᯠáááºááŒá±á¬áá«áááá·áºáááºá á€áá±áá¬ááœáẠááœááºáá²á·ááá·áº 15 ááŸá áºá¡ááœááºáž Microsoft á áá±ážáá±á¬ááºáá²á·áá±á¬ .net ááœáẠá¡áá®á¡áá»áŸ áá±á¬áºáááºáá»á¬áž ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯á áááá¯ááºážááŒá±á¬ááºáž áá áºáá¯áá¯á¶ážááᯠááŸááºáá¬ážáá¬ážááááºááŒá áºááŒá®ážá Task-Based Asynchronous Pattern (TAP) áááá¯ááºáá®ááœáẠAsynchronous Programming Pattern (APP) ááŸááá²á·áá«áááºá áááºážáááºážáá»á¬ážá¡ááŒá±á¬ááºážááŒá áºáá²á·áááºá á¡á áá áºáá¯áá¯ááŒááºáá¯ááºáá«á IAsync áááẠááŸáá·áºáááºážáááºážáá»á¬áž á¡áá¯á¶ážáááºážááá¯áááºáá¶ááá·áº DoSomething ááŸáá·áº á€ááŸá áºáá»á¬ážá á¡ááœá±á¡ááŸá áºá¡ááœáẠFromAsync áááºážáááºážááẠááŒá®ážááŒáá·áºá á¯á¶áá±á¬áºáááºáž á¡áá»áááºááŒá¬áá¬áááºááŸáá·áºá¡áá»áŸ áááºážááᯠEvent Based Asynchronous Pattern ááŒáá·áº á¡á á¬ážááá¯ážáá²á·ááẠ(AND AP) asynchronous áá¯ááºáá±á¬ááºááŸá¯ ááŒá®ážááŒá±á¬ááºáá±á¬á¡áá«ááœáẠááŒá áºáááºáá áºáᯠáá±á«áºáá±á«ááºáá¬áááºáᯠáá°ááá«áááºá
TaskCompletionSource ááẠááœá²áá±á¬áºáááºáááá¯ááºááœáẠáááºáá±á¬ááºáá¬ážáá±á¬ Tasks áá»á¬ážááŸáá·áº á¡ááœá±á¡ááŸá ẠAPI áá»á¬ážááᯠáá¯ááºááá¯ážáááºá¡ááœáẠááŒá®ážááŒáá·áºá á¯á¶áá«áááºá áááºážáá¡áá¯ááºáá¡ááŸá áºáá¬áááŸá¬á¡á±á¬ááºáá«á¡ááá¯ááºážááŒá áºáááº- á€á¡áááºážáá¡áá¬ááá¹áá¯áá áºáá¯ááœáẠTask á¡áá»áá¯ážá¡á á¬ážá á¡áá»á¬ážáá°ááŸá¬ááá¯ááºááá¯ááºááŸá¯áá áºáá¯ááŸáááŒá®ážá TaskCompletionSource á¡áááºážá SetResultá SetException á áááºááá¯á·ááŸáááá·áº ááááºážáá»á¯ááºááá¯ááºááá·áº á¡ááŒá±á¡áá±á ဠTask á¡ááœáẠá á±á¬áá·áºááá¯ááºážáá±áá±á¬ á¡á±á¬áºááá±áá¬á¡á¬áž á¡áá¯á¶ážáá»ááá·áºáá±áá¬áá»á¬ážááœáẠTaskCompletionSource ááœááºá¡áá¯á¶ážááŒá¯ááá·áºáááºážáááºážáá±á«áºáá°áááºá áááºážááᯠáá¯ááºáá±á¬ááºááẠááá¯á·ááá¯áẠáá»ááºááœááºááœá¬ážáááºááŒá áºáááºá áááŸááºážáááºážáá±ážáá«áá EAP API á¡áá±á¬ááºážá¡áá»áá¯á·ááᯠTaskCompletionSource ááᯠá¡áá¯á¶ážááŒá¯á Task áá áºáá¯ááœáẠáá¯ááºááá¯ážáá¬ážááá·áº á€áá¯ááºááá°áá¬ááᯠááŒáá·áºááŒáá«á áá¯á·- á¡ááŒá áºá¡áá»áẠáá®ážáá±á¬ááºááœá¬ážáá±á¬á¡áá« Task ááẠCompleted á¡ááŒá±á¡áá±ááá¯á· ááŒá±á¬ááºážááœáŸá±á·ááœá¬ážáááºááŒá áºááŒá®ážá á á±á¬áá·áºáá±áá±á¬ á¡á±á¬áºááá±áá¬ááᯠá¡áá¯á¶ážááŒá¯ááá·áº áááºážáááºáž ဠTask ááẠá¡áá¬ááá¹áá¯ááᯠáááºáá¶áááŸáááŒá®ážáá±á¬áẠáááºážááá¯ááºáá±á¬ááºááŸá¯ááᯠááŒááºáááºá áááºáááºááŒá áºáááºá ááááº.
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 Tips & Tricks
API á¡áá±á¬ááºážáá»á¬ážááᯠáá¯ááºááá¯ážááŒááºážááẠTaskCompletionSource ááᯠá¡áá¯á¶ážááŒá¯á áá¯ááºáá±á¬ááºááá¯ááºááá»áŸ ááá¯ááºáá«á á€á¡áááºážááá¯á¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áº thread áá»á¬ážááá¯áááááºážááá¯ááºááá¯ááºáá±á¬ Tasks áá»á¬ážááœáẠá¡áá»áá¯ážáá»áá¯ážáá±á¬ API áá»á¬ážááᯠáá®ááá¯ááºážááœá²ááẠá áááºáááºá á¬ážááœááºááŒá áºááá¯ááºááŒá±ááᯠááœáá·áºáá±ážáááºá áá»áœááºá¯ááºááá¯á·ááŸááºááááá·áºá¡ááá¯ááºážá á á®ážááŒá±á¬ááºážááẠá á»á±ážááŒá®ážáá±á¬á¡áááºážá¡ááŒá áºááŒá áºááŒá®áž áááºážááá¯á·áá¡áá±á¡ááœááºááᯠááá·áºáááºáá¬ážááẠ(á¡áááá¡á¬ážááŒáá·áº RAM ááá¬áá¡á¬ážááŒáá·áº)á á¥ááá¬á¡á¬ážááŒáá·áº ááŸá¯ááºááœá±ážáá±á¬ á á®ážááœá¬ážáá±ážáá¯áá¹ááááŸááá±á¬ áááºá¡ááºááá®áá±ážááŸááºážááᯠáá®ááœááºááŒááºážááŒáá·áº á€ááá·áºáááºáá»ááºááᯠá¡ááœááºááá° á¡á±á¬ááºááŒááºááá¯ááºáááºá Long-Polling áá²á·ááá¯á·áá±á¬ ááŸáá·áºááœááºáá»á¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáá¬ááœáẠáá»áœááºá¯ááºááŒá±á¬áá±ááá·áº ááŒá áºááá¯ááºááŒá±áá»á¬ážááᯠáá¯á¶ážáááºááŒáá·áºááŒáá«á áá¯á·á
á¡ááá¯áá»á¯ááºá¡á¬ážááŒáá·áºá ááŸáá·áºááœááºá á¡ááŸá áºáá¬áááŸá¬ á€á¡áá¬ááŒá áºáááº- áááºážááááºá០ááŒá áºáá»ááºáá±ááá·áº á¡áá»áá¯á·áá±á¬ááŒá áºáááºáá»á¬ážá¡ááŒá±á¬ááºáž API á០á¡áá»ááºá¡áááºáá»á¬áž ááá°ááẠááá¯á¡ááºáá±á¬áºáááºážá á¡ááŒá±á¬ááºážáá áºáá¯áá¯ááŒá±á¬áá·áº API ááẠááŒá áºáááºááᯠááááºážáááá¯á·ááá¯ááºáá±á¬áºáááºáž á¡ááŒá±á¡áá±ááá¯áᬠááŒááºáá±ážááá¯ááºáááºá á¥ááá¬áá áºáá¯ááẠWebSocket áá±ááºáááá¯ááºáá® ááá¯á·ááá¯áẠá€áááºážááá¬ááᯠá¡áá¯á¶ážááŒá¯ááẠá¡ááŒá±á¬ááºážáá áºáá¯áá¯ááŒá±á¬áá·áº áááŒá áºááá¯ááºááá·áºá¡áá« HTTP áááááºááœáẠáááºáá±á¬ááºáá¬ážáá±á¬ API áá»á¬ážá¡á¬ážáá¯á¶ážááŒá áºáááºá client ááẠHTTP server ááá¯áá±ážááá¯ááºáááºá HTTP áá¬áá¬ááẠáááá¯ááºážááá·áºááŸáá·áº áááºááœááºááŸá¯ áá áááºááá¯ááºáá«á ááá¯ážááŸááºážáá±á¬ááŒá±ááŸááºážáá»ááºááŸá¬ á¡áá»áááºááá¯ááºážáááááá¬ááᯠá¡áá¯á¶ážááŒá¯á áá¬áá¬ááᯠá á áºáááºážáá±á¬ááºáá°áááºááŒá áºáá±á¬áºáááºáž áááºážááẠáá¬áá¬ááœáẠá¡ááá¯áááºááá¯á¡á¬ážááŸáá·áº áá»ááºážáá»áŸ TimerInterval / 2 ááœáẠáá±á¬ááºáááºááŸá±á¬áá·áºááŸá±ážááŸá¯ááᯠáááºáá®ážáá±ážáááºá áááºážááá¯ááŒá±ááŸááºážáááºá áá¯á¶á·ááŒááºááŸá¯ááá¯ááŸá±á¬áá·áºááŸá±ážá á±ááá·áº Long Polling áá¯áá±á«áºáá±á¬ááŸáá·áºááœááºááᯠáá®ááœááºáá²á·áááºá áá¬áᬠáááºáááºážáá¯ááºáá¯á¶ážáá»áááºá¡áá ááá¯á·ááá¯áẠááŒá áºáááºáá áºáᯠááŒá áºáá±á«áºáááºááŒá áºáááºá ááŒá áºáááºáá áºáᯠááŒá áºáá±á«áºáá¬áá«á áááºážááᯠá á®áá¶áá±á¬ááºááœááºáááºá ááá¯ááºáá«á áá±á¬ááºážááá¯áá»ááºááᯠáááºáá¶áá±ážááá¯á·áááºááŒá áºáááºá
while(!eventOccures && !timeoutExceeded) {
CheckTimout();
CheckEvent();
Thread.Sleep(1);
}
áá«áá±ááá·áº ááœá²á¡ááœááºá á±á¬áá·áºááá¯ááºážáá±áá²á· áá±á¬ááºáááºá¡áá±á¡ááœáẠááá¯ážáá¬áá¬áá²á·á¡áá»áŸ áá®ááá¯ááŒá±ááŸááºážáá»ááºáᬠááŒá±á¬ááºá áá¬áá±á¬ááºážáá±á¬ááºá¡á±á¬áẠááá¯ážááœá¬ážáá¬ááŸá¬ ááŒá áºááá¯á·... ááá¯ááá¯á·áá±á¬ client áá áºáá¯á á®ááẠááœá²áá áºáá¯á¡ááœáẠá á±á¬áá·áºááá¯ááºážáá±áá±á¬ thread áá áºáá¯áá¯á¶ážááᯠááááºážááá¯ááºáá¬ážáááºá áá¯ááºáá«áááºá ááŒá áºáááºááᯠá¡á áá»áá¯ážáá±á¬á¡áá« áá±á¬ááºááẠ1ms ááŸá±á¬áá·áºááŸá±ážááŸá¯ááᯠáá»áœááºá¯ááºááá¯á·áááŸááááºá á¡áá»á¬ážá á¯ááŸá¬ áááºážááẠáááááá¬áá¬ááá¯ááºáá±á¬áºáááºáž áá±á¬á·ááºáá²ááºááᯠááŒá áºááá¯ááºáááºááẠá¡áááºááŒá±á¬áá·áº ááá¯ááá¯ážá á±ááááºážá á¡áááºá áá»áœááºá¯ááºááá¯á·ááẠThread.Sleep(1) ááᯠáááºááŸá¬ážáá«á á¡áá»ááºážááŸá®ážááŒá áºááŒá®áž á¡áá¯á¶ážááááºáá±á¬ á ááºáááºážááœáẠáááºáááºáá±áá±á¬ áááá¯áááºáᬠcore áá áºáá¯á¡á¬áž 100% idle ááᯠáááºáá«áááºá 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 áááºážáááºážááẠááŒá®ážááœá¬ážááá·áº Task áá áºáá¯ááᯠááŒááºáá±ážááá·áºáááºá áá«á á¡ááŒá áºá¡áá»á¬ážáá¯á¶ážááá á¹á ááá¯ááẠValueTask ááá¯áá¯á¶ážááá¯á· á ááºážá á¬ážááá¯ááºáá«áááºá
áááºáá±á·áá»áºáá áºáá¯á¡ááœáẠáá±á¬ááºážááá¯ááŸá¯áá áºáá¯ááᯠáá»áœááºá¯ááºááá¯á·áááºáá¶áááŸáááá·áºá¡áá«á áá»áœááºá¯ááºááá¯á·ááẠTaskCompletionSource ááᯠá¡áááá¬ááºááœáẠáááºáá®ážááŒá®áž áá¬ážááŸááᬠááŒá áºáá»ááºááá·áºá¡áá¬ááᯠáŠážá áœá¬á á±á¬áá·áºááá¯ááºážáá«- áááºááŸááºáá¬ážáá±á¬á¡áá»áááºááŒá¬ážáá¬á áá¯ááºáá¯á¶ážááœá¬ážááẠááá¯á·ááá¯áẠáááºáá±á·áá»áºáá áºáᯠáááºáá¶áááŸááááºááŒá áºáááºá
ValueTask- á¡áááºááŒá±á¬áá·áºáááºáž
yield return operator áá²á·ááá¯á· async/ait operator áá»á¬ážááẠmethod á០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);
}
á¡ááŸááºá ááºá á áºá á€ááá á¹á ááœáẠá¡áá±á¬ááºážáá¯á¶ážááŒá±ááŸááºážáá»ááºááŸá¬ hot-path ááᯠá¡áá±á¬ááºážáá¯á¶ážááŒá áºá¡á±á¬ááºá ááŒá±á¬ááááºá áááá¯á¡ááºáá² ááœá²áá±áá»áá¬ážááŒááºážáááŸááá² á¡áááá¬ááºááŸáááºááá¯ážáá áºáá¯ááá°ááŒá®áž 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 ááŸá¬ class ááŒá áºáááºá TaskScheduler ááŸáá·áº áááºážá áááºážáááºáá¬áááºá TPL ááœáẠTasks áá»á¬ážááᯠááá¹ááá»á¬ážá¡ááŸá¶á· ááŒáá·áºáá±ááŒááºážá¡ááœáẠááá¬áá»á°áá¬áá»á¬ážááᯠá á®áá¶ááá·áºááœá²ááá¯ááºá áœááºážááŸáááŒá±á¬ááºáž á¡áá±á«áºááŸá¬ááŒá±á¬áá²á·ááŒá®ážáá«ááŒá®á ááá¯áá²á·ááá¯á·áá±á¬ áááºážáá»á°áá¬áá»á¬ážááᯠTaskScheduler á¡áááºážá áá»áá¯ážáááºáá»á¬ážááœáẠáááºááŸááºáá¬ážáá«áááºá áááºááá¯á¡ááºááá¯ááºááá·áº áááºááá·áºáááºážáá»á°áá¬ááá¯áááᯠá á¬ááŒáá·áºááá¯ááºááœáẠááœá±á·ááá¯ááºáá«áááºá ParallelExtensionsExtrasMicrosoft á០áááºáá®ážáá¬ážáá±á¬áºáááºáž .NET á áá áºá áááºáá áºááá¯ááºážááá¯ááºáá±á¬áºáááºáž Nuget áááºáá±á·áá»áºá¡ááŒá Ạáá¶á·ááá¯ážáá¬ážáááºá áááºážááá¯á·áá²á០á¡áá»áá¯á·ááᯠá¡ááá¯áá»á¯á¶ážááŒáá·áºááŒáá«á áá¯á·á
- CurrentThreadTask á¡á á®á¡á ááºááœá²áá° - áááºááŸá thread ááœáẠTasks ááᯠáá¯ááºáá±á¬ááºáááºá
- LimitedConcurrencyLevelTask ââá¡á á®á¡á ááºááœá²áá° - constructor ááŸáááºáá¶ááá·áº parameter N ááŒáá·áº áááŒáá¯ááºááẠáá¯ááºáá±á¬ááºááá·áº Tasks á¡áá±á¡ááœááºááᯠááá·áºáááºáááº
- OrderedTaskScheduler â LimitedConcurrencyLevelTaskScheduler(1) á¡ááŒá ẠáááºááŸááºáá¬ážáá±á¬ááŒá±á¬áá·áº á¡áá¯ááºáá»á¬ážááᯠáááºááá¯ááºáá¯ááºáá±á¬ááºáá«áááºá
- WorkStealingTask á¡á
á®á¡á
ááºááœá²áá° - á¡áá¯á¶ážá¡áá±á¬ááºáá»á¬áž
á¡áá¯ááºááá¯ážááŒááºážá á¡áá¯ááºááœá²áá±ááŒááºážááá¯á·áá»ááºážáááºááŒááºážá á¡ááŒá±áá¶á¡á¬ážááŒáá·áº áááºážááẠáá®ážááŒá¬áž ThreadPool ááŒá áºáááºá .NET ThreadPool ááẠá¡ááá®áá±ážááŸááºážá¡á¬ážáá¯á¶ážá¡ááœáẠáá áºáá¯áááºážáá±á¬ static class áá áºáá¯ááŒá áºááŒá®ážá ááá¯ááá¯áááºááŸá¬ áááá¯ááááºáá áºáá¯á á¡á áááºá¡ááá¯ááºážáá áºáá¯ááœáẠáááºážá overloading ááá¯á·ááá¯áẠááŸá¬ážááœááºážá áœá¬á¡áá¯á¶ážááŒá¯ááŸá¯ááẠá¡ááŒá¬ážáá áºáá¯ááœáẠáá±ážááœááºááá¯ážáá»áá¯ážáá»á¬ážááŒá áºáá±á«áºá á±ááá¯ááºáááºáá°áá±á¬ ááŒá¿áá¬ááᯠááŒá±ááŸááºážáá±ážáá«áááºá ááá¯á·á¡ááŒááºá ááá¯ááá¯á·áá±á¬áá»áá¯á·ááœááºážáá»ááºáá»á¬ážáá¡ááŒá±á¬ááºážáááºážááá¯áá¬ážáááºáááºá¡ááœááºáááºáá²áááºá á¡á²áá«á ThreadPool á¡áá¯á¶ážááŒá¯ááŸá¯ááẠááŒááºážáááºááŒá®áž ááá·áºááŸááºážááááºááá·áº áááá¯ááááºá á¡á áááºá¡ááá¯ááºážáá»á¬ážááœáẠáá®ážááŒá¬áž WorkStealingTaskSchedulers ááᯠá¡áá¯á¶ážááŒá¯ááẠááá¯á¡ááºáá«áááºá - QueuedTaskScheduler - áŠážá á¬ážáá±ážáááºážá á®á ááºážáá»ááºážáá»á¬ážááŸáá·áºá¡áá® á¡áá¯ááºáá»á¬ážááᯠáá¯ááºáá±á¬ááºááá¯ááºá á±áá«áááºá
- ThreadPerTaskScheduler â áááºážááœáẠáá¯ááºáá±á¬ááºááá·áº Task áá áºáá¯á á®á¡ááœáẠáá®ážááŒá¬áž thread áá áºáá¯ááᯠáááºáá®ážáááºá ááŒá®ážááŒá±á¬ááºááẠáááá·áºááŸááºážááá¯ááºáá±á¬ á¡áá»áááºááŒá¬ááŒáá·áºááá·áº á¡áá¯ááºáá»á¬ážá¡ááœáẠá¡áá¯á¶ážáááºááá¯ááºáááºá
áá±á¬ááºážáá±á¬ááºážá¡áá±ážá
áááºááŸááá«áááºá
Tasks ááŸáá·áº áááºáááºááá·áº á¡áá¬á¡á¬ážáá¯á¶ážááᯠá¡áááºááŒá±ááŒá± á¡ááŸá¬ážááŸá¬ááŒááºážá¡ááœáẠVisual Studio ááœáẠTasks áááºážááá¯áž ááŸááááºá á€áááºážááá¯ážááœáẠáááºááẠáá¯ááºáááºážáá±á¬ááºáá¬á áááºááŸáá¡ááŒá±á¡áá±ááᯠááŒááºááá¯ááºááŒá®áž áááºááŸááá¯ááºáá±á¬ááºáá±áá±á¬ áá¯ááºááá¯ááºážááá¯á· áá¯ááºáááºážááá¯ááºáááºá
PLinq ááŸáá·áº Parallel á¡áááºáž
Tasks ááŸáá·áº áááºážááá¯á·ááŸáá·áºáááºáááºááá·áºá¡áá¬á¡á¬ážáá¯á¶ážá¡ááŒááºá .NET ááœáẠááá¯ááá¯á
áááºáááºá
á¬ážá
áá¬áá±á¬ááºážáá±á¬áááááá¬ááŸá
áºáá¯ááŸááááº- PLinq (Linq2Parallel) ááŸáá·áº Parallel á¡áááºážá áááá¡áá»ááºá ááá¯ááºážáá»á¬ážá
áœá¬ááœáẠLinq áááºáááºááŸá¯á¡á¬ážáá¯á¶ážááᯠá¡ááŒáá¯ááºáá¯ááºáá±á¬ááºáááºáᯠááááá±ážáááºá WithDegreeOfParallelism ááá¯ážáá»á²á·ááŸá¯áááºážáááºážááᯠá¡áá¯á¶ážááŒá¯á á
á¬ááœá²á¡áá±á¡ááœááºááᯠááŒááºáááºáááºááŸááºááá¯ááºáááºá áá¶ááá±á¬ááºážá
áœá¬áá²á áááŒá¬ááááá¯áááᯠPLinq ááẠáááºážááá°ááá¯ááºááœáẠáááá¬áááºááŸá¬ážáá±á¬á¡ááŒááºááŸá¯ááºážáááŸáááẠááá·áºáá±áá¬á¡áááºážá¡ááŒá
áºáá¡ááœááºážááá¯ááºážááŸáá·áºáááºáááºááá·áº áá¯á¶áá±á¬ááºáá±á¬á¡áá»ááºá¡áááºáááŸááá«á á¡ááŒá¬ážáá
áºáááºááœááºá ááŒáá¯ážá
á¬ážáááºáá¯ááºáá»á
ááááºááẠá¡ááœááºáááºážáá«áááº- ááẠAsParallel áááºážáááºážááᯠááá±á«áºááá¯áá®ááœááºáᬠááá¯á¡ááºáá«áááºá Linq áááºážáááºážáá»á¬ážáááœááºážáááºááŸáá·áº á
áœááºážáá±á¬ááºáááºá
á
áºáá±ážááŸá¯áá»á¬ážááᯠáá¯ááºáá±á¬ááºáá«á ááá¯á·á¡ááŒááºá Partitions ááá¹ááá¬ážááᯠá¡áá¯á¶ážááŒá¯á áááºááá±áá¬áááºážááŒá
áºáááá±á¬ááá¬áááŸáá·áºáááºáááºááá·áº PLinq ááá¯á· áá±á¬ááºáááºá¡áá»ááºá¡áááºáá»á¬ážááᯠáá±ážááá¯á·ááá¯ááºáááºááŒá
áºáááºá á
á¬áá»á¬ážáá»á¬ážáááºááá¯á·ááááºá
Parallel static class ááẠForeach á á¯á ááºážááŸá¯á¡á¬áž á¡ááŒáá¯ááºááŒá¯áá¯ááºááŒááºážá For loop ááá¯áá¯ááºáá±á¬ááºááŒááºážááŸáá·áº parallel Invoke ááœáẠááá¯ááºá á¬ážááŸááºáá»á¬ážá áœá¬ááᯠáá¯ááºáá±á¬ááºááŒááºážá¡ááœáẠáááºážáááºážáá»á¬ážááᯠáá¶á·ááá¯ážáá±ážáá«áááºá ááœááºáá»ááºááŸá¯áá»á¬áž áááŒá®ážááá»ááºáž áááºááŸáá á¬ááœá²á áá¯ááºáá±á¬ááºááŸá¯ááᯠáááºááá·áºáá«áááºá áá±á¬ááºáá¯á¶ážá¡ááŒááºážá¡áá¯á¶á¡ááŒá ẠParallelOptions ááá¯ááŒááºáááºážááŒááºážááŒáá·áº thread á¡áá±á¡ááœááºááᯠconfigure áá¯ááºááá¯ááºáá«áááºá ááœá±ážáá»ááºááŸá¯áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á TaskScheduler ááŸáá·áº CancellationToken ááá¯á·ááá¯áááºáž áááºááŸááºááá¯ááºáá«áááºá
ááœá±á·ááŸááá»ááºáá»á¬áž
áá»áœááºá¯ááºáá¡á á®áááºáá¶á á¬áá«á¡ááŒá±á¬ááºážá¡áá¬áá»á¬ážááŸáá·áº áááºážááŒá®ážáá±á¬áẠáá»áœááºá¯ááºááá¯ááºáááºážááœááºá¡ááœááºáž á á¯áá±á¬ááºážáááŸááá¬ážáá±á¬ á¡áá»ááºá¡áááºáá»á¬ážá¡áá±á«áº á¡ááŒá±áá¶á á€áá±á¬ááºážáá«ážááᯠá áááºáá±ážáá¬ážáá±á¬á¡áá«ááœáẠá€áá»áŸáá±á¬ááºáá»á¬ážááŒá¬ážáááºáᯠááá»áŸá±á¬áºááá·áºáá²á·áá«á ááᯠá€áá±á¬ááºážáá«ážááᯠáá»áœááºá¯ááºááá¯ááºáá±áá±á¬ á á¬áá¬ážáááºážááŒááºáá°ááẠá á¬áá»ááºááŸá¬ áá áá«ááœá¬ážááŒá®áᯠáá»áœááºá¯ááºá¡á¬áž áá²á·áá²á·ááŸá¯ááºáá»áá±á¬á¡áá«á ááŒá¬ážááŒááºááááºáá»á¬ážááᯠá¡áá»ááºážáá»á¯á¶ážáá«áááºá á¡ááŒá¬ážáá±á¬ ááŸáá·áºááœááºáá»á¬ážá API áá»á¬ážá á¡ááŒááºá¡á¬áá¯á¶áááááá¬áá»á¬ážááŸáá·áº ááŒá¿áá¬áá»á¬ážááᯠáá±á¬ááºáá±á¬ááºážáá«ážááœáẠáá±á¬áºááŒáá«áááºá
áá±á¬ááºáá»ááº:
- áá±ááºáá® PC áá»á¬ážáá¡áááºážá¡ááŒá áºáá»á¬ážááá¯á¡áá¯á¶ážááŒá¯áááºá¡ááœáẠthreadsá asynchrony ááŸáá·áº parallelism ááá¯á·ááŸáá·áºá¡áá¯ááºáá¯ááºááẠtools áá»á¬ážááá¯áááºáááááºááá¯á¡ááºáááºá
- .NET ááœáẠá€áááºááœááºáá»ááºáá»á¬ážá¡ááœáẠááá°áá®áá±á¬áááááá¬áá»á¬ážá áœá¬ááŸááááºá
- áááºážááá¯á·á¡á¬ážáá¯á¶ážááẠáá áºááŒáá¯ááºáááºáá±á«áºáá¬ááŒááºážááá¯ááºáá±á¬ááŒá±á¬áá·áº áááºááẠá¡ááœá±á¡ááŸá áºáá»á¬ážááᯠáááŒá¬ááááŸá¬ááœá±ááá¯ááºáá±á¬áºáááºážá á¡á¬ážá áá¯ááºáá¯ááºá áá¬áááá¯áá² API á¡áá±á¬ááºážáá»á¬ážááᯠááŒá±á¬ááºážáááºáááºážáááºážáá»á¬ážááŸááá«áááºá
- .NET ááœáẠthread áá»á¬ážááŸáá·áºá¡áá¯ááºáá¯ááºááŒááºážááᯠThread ááŸáá·áº ThreadPool á¡áááºážáá»á¬ážááŸááá¯ááºá á¬ážááŒá¯áááºá
- Thread.Abortá Thread.Interrupt ááŸáá·áº Win32 API TerminateThread áááºážáááºážáá»á¬ážááẠá¡áá¹ááá¬ááºááŸáááŒá®áž á¡áá¯á¶ážááŒá¯ááẠá¡ááŒá¶ááŒá¯áá¬ážááŒááºážáááŸááá«á áááºážá¡á á¬ážá CancellationToken ááá¹ááá¬ážááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááẠááá¯áá±á¬ááºážáááºá
- á á®ážáááºážááŸá¯ááẠáááºááá¯ážááŸááá±á¬ á¡áááºážá¡ááŒá áºááŒá áºááŒá®áž áááºážá áá±á¬ááºáá¶á·ááŸá¯ááŸá¬ á¡ááá·áºá¡áááºááŸááááºá ááœá²áá»á¬ážááᯠá á±á¬áá·áºáá»áŸá±á¬áºáá±áá±á¬ ááá¯ááºážáá»á¬áž á¡áá¯ááºááŸá¯ááºáá±ááá·áº á¡ááŒá±á¡áá±áá»á¬ážááᯠááŸá±á¬ááºááŸá¬ážááá·áºáááºá áááºážá¡ááœáẠTaskCompletionSource á¡áááºážááᯠá¡áá¯á¶ážááŒá¯ááẠá¡áááºááŒá±áááºá
- Parallelism ááŸáá·áº asynchrony ááŸáá·áº áá¯ááºáá±á¬ááºáááºá¡ááœáẠá¡á áœááºážáááºáá¯á¶ážááŸáá·áº á¡ááá·áºááŒáá·áº .NET áááááá¬áá»á¬ážááẠTasks áá»á¬ážááŒá áºáááºá
- c# async/await á¡á±á¬áºááá±áá¬áá»á¬ážááẠááááºááá¯á·ááŒááºážááá¯ááºáá±á¬ á á±á¬áá·áºááá¯ááºážááŒááºážááá±á¬ááá¬ážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá
- TaskScheduler ááŸáááŸááá±á¬ á¡áááºážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á á á¬ááœá²áá»á¬ážáá áºáá»áŸá±á¬áẠTasks áá»á¬áž ááŒáá·áºáá±ááŸá¯ááᯠáááºááááºážáá»á¯ááºááá¯ááºáááºá
- ValueTask ááœá²á·á ááºážáá¯á¶ááẠhot-paths ááŸáá·áº memory-traffic ááᯠáá±á¬ááºážááœááºá¡á±á¬ááºááŒá¯áá¯ááºáá¬ááœáẠá¡áá¯á¶ážáááºáá«áááºá
- Visual Studio á Tasks and Threads windows ááẠmulti-threaded ááá¯á·ááá¯áẠasynchronous code ááᯠá¡ááŸá¬ážááŸá¬ááŒááºážá¡ááœáẠá¡áá¯á¶ážáááºáá±á¬ á¡áá»ááºá¡áááºáá»á¬ážá áœá¬ááᯠáá±ážáá±á¬ááºáááº
- PLinq ááẠáá±á¬ááºážááœááºáá±á¬áááááá¬áá áºáá¯ááŒá áºáá±á¬áºáááºáž ááá·áºáá±áá¬áááºážááŒá áºááŸáá·áºáááºáááºá áá¯á¶áá±á¬ááºáá±á¬á¡áá»ááºá¡áááºáááŸáááá¯ááºáá±á¬áºáááºáž áááºážááᯠááá¯ááºážááŒá¬ážááŒááºážááá¹ááá¬ážááᯠá¡áá¯á¶ážááŒá¯á ááŒááºáááºááá¯ááºáááºá
- áááºáááºâŠ
source: www.habr.com