αααα»ααααα»αααααα»αααα’αααααααΎααα
ααΎ Habr αααααΆααΆααααααααααααααΌαααΆααααα αααα
αααα»αααΆααΈααααα
αααααΌαααΆαααΎααααΈααααΎα’αααΈαα½ααααα’ααααΆα ααααα·ααααα
αΆααααααααα
ααΈααα αα·αα₯α‘αΌαααα α¬ααΎααααΈαααα
ααααΆαααΆααα α αααα»αα
ααααα’αααααΆαααΆα
αααΎααααα’αα»ααααααΆααΆααα»αααΆαααααααααα»αααααΌαααα ααΆαα½αααΉαααααααΆααααααα½ααα αααααΌαααΆααααααΆαααααΆαααΆααΆαααααααααΆααα α₯α‘αΌαααααα
αααα»αααααΆα 2019 αααα»ααααα»αααΆαα’αααααααααα
ααΎαα»αααααΌααααα½ααααααααΆαααααααααααααΎαααΆα 8-core Intel Core αααααααΎαααΆαααΆααα½ααααααα»αααααΎαααΆαααααααααΆ αα·αααΌααααΈαααααααααα‘αΆαααΆα
αααΎααααα αα
βαααααβαααβααΆαβααΌαααααβααΆαβαααα½αβααααα·α
βαααβααΆαβαα·αβααΆαβααΈβααα»ααααΆαβααααΆαβαα»α ααΆβααΆαβααααααααβααααΎαααΆα 8-core αα
βααΎβααααα ααα ααααΆααααααΆαααααΊαααααααα
αααα’ααααα αα·αααΈααα’αΌ αααα’ααααα·αααααααααα½ααααααααααΎαα
ααααααααΆαα αααΌαααααΌααααα»αααααΆαααα αααααααΆααααΌαααααααααααααΎαααΆα 16-coreα MS Azure ααααααααΆαααΈααα·αααα·αααΆαα½αααΉααα½αααααΆα 20 core αα·α RAM 128 TB αααα»αααααααα·α
ααΆα $2 αααα»ααα½αααααα ααΆα’αα»αα ααΆαα·αα’αΆα
αα
αα½α
αααααα»αααΆαααΆαααα’αα·ααααΆ αα·αααααΎααααΆααααΆααααααααααα·αα’αΆα
αααααααααα’αααααααααααααααααα‘αΆαααΆαααα
ααααα
ααααΎαααΆα - ααααα» OS, α
αααααα’αΆααααααΆαααΆα
ααααααΆα, ααΆααααααααα‘αΆαα
αααααααα‘αΆα - ααααα» OS αααααΆα’αααααΆαααΌα
αααα»αααααΆαααααα·ααααα· ααΆαααααααααααΎαααΆα αααααααα‘αΆαα
αααααααα’αααα
αα
αΆα αα·αααααΆααααααααααααα»αα
αααααα½ααααα
αααα»αααααΎαααΆααα½αα
αα α»αα»αααΆα - ααααααααααααα· OS αααααααΆααααα»αααΆαααααΎαααΆαααααΎαααΆαααΆα
αααΎααααα»ααααααααΆαααααΆα
αα α»ααααΌα - αααααααααααααα·αααα processor αααααααΆαααααΎααααΆααααααΌαααΆα
αααΎααααααΆααααααΎαααΆααα·αααααα
ααααΎαααΆαα
αααΎαα - αααααααααααααα·αααααα»αααααΌααα αααααααΆααααα»αααΆαααααΎααΆααααα»ααααααααΆαααααΆααΆαα½α processors ααΆα
αααΎαααΌα
αα α»αααα - αααααααααααααα·ααααααΎαααΆααα½α αααααααΆααααα»αααΆαα
ααα
αΆαααααΎαααΆααα·αααααααααα»αα
αααααααααααα‘αΆαααΆα
αααΎαα
ααΆαααααααααΆα - α’αα»αααααααααααΆαααΆαααΆαααΆα
αααΎααααα»ααααααααΆαααααΆαααα»ααα½αα―αααΆαααααααααΆ
α’ααααΆα - ααΆαααααα·ααααα·ααααααα·ααααα·ααΆαααααα·ααααα
αΆαααΆααααα
ααααααααΎαααΆαααα ααααααααααΆαααααα·ααααα·α’αΆα
ααααΌαααΆαααααΎαααΆααα
ααααααααα
ααΆαααααααααα
αα·αααααα·αααααααΆααα’αααα»αααααααα’αα α αΎαααααααααΌαααΆαααΆααααααααααααα ααΌα αααααααα»αααΉαααααααααΆαααααααααααα’αααΈααΆαα ααα’α·αα’αΆα αΆαα’αΆα αΆααααααααΉααα ααΆααααααααααΆαααΆααααΌαααΆαα ααΆαα ααα’α·αα’αΆα αΆααααααααΉααα αααα»αααΆααααααααααααααααΊααΆααααΎαααΆααα½αα
ααααααα»ααααα αα’αΆα αΆααααααααΉα αααα»α (αααΈααΈααΌ) αααα»αααααααααΆα (αα»αααααΌαααα) αααα»αααΆααα 2 (ααααΌα) ααΆαα§αααααααΆα αααΎααα αααα»αααααααΆα (IO) : oven, kettle, toaster, ααΌααΉαααα αααα»αβααΎαβα αααΆα ααΆααβααααβα ααβααΎβααΆ α αΎαβα αΆααβαααααβα αΌαβαααβαα·αβα αΆαβααΆβα‘αΎαβαααα (α’ααααΆα, αα·ααααααααΆαα-IO-αααα αΆα) αααα»αααααα»αα ααααΈααΌααΉααα α αΎααααααααΆα αΌααα αααα»αα αΆα αααααΆααααααΆαααΆαααααααααΆα (αααααααα‘αΆαααα 1), αα·αααΈααΈα (αααααααα‘αΆαααα 2) ααΆααα αΆα (ααααΆαα ααααααα) α α₯α‘αΌαααααααα»αα ααααΎαααααα ααα»αααααααα»ααα·αααΆααααααααααααΆαα (ααΆαα’ααααααΆααααααααα‘αΆα) αααα»αα’αα‘α»αααααααααααα ααα‘αΎααααα (ααααΎαααΆααααααα) ααααααα»αα αΆααα’αααΈααααααα»αααΆα whipped α αααα»αβαααβαα βααβαααααβααΎαβα αΎαβααΎαβααΉαβαααβαα»αβαααα»αβααα (ααΆααααααααΆαα-IO-αααα αΆα) αααααΈααΆαααα»αα’αα‘α»αααααααααΆααα’αΆα ααΆαα αΆααααααΆαααααααααααΆααααΆα whipped omelet α
αααα»αβα ααα’α·αβα’αΌβααβα‘ααβαααβααααΎβααβα’βααβααα»ααααα α αΎαβαααα»αβα’ααβααΆαβαααβαα ααα»ααααβαα βαααβααααΆαααααΆβααΉαβααΆαβααΆαβααβα’αΌβααβα‘αβαβααα ααααα·ααααα·ααΆαβα£βααΆαβααΎαβα‘αΎαβαααα»αβαααβααβαα½αβα ααΆαβααΆαβααβα’αΌβααβα‘αα ααΆααβα αΆαβα‘αΎαβαααα βαααα α αααΈααΈααΌααΊααΆααααααααααΏααααα»ααααααα»αααααΌααα IO ααΊααΆα’αααΈαααααΆαα αααΎααααααααααΎαααΆαααΊα ααΌα ααααααΆααΏαααααααααααΆαααααΆαααααα·αααααΆαααΊααΆαααΆααααΆαααααΈααΈααΌααΆαα½αααΉαα’αααΈαα½α αααααααααααα½ααα·ααααααααΈ IO α
ααΆαααααααΆαααααααααα
- ααααα·αααΎαα αααα»αααααΎαααΆαααααΆααααα α omelet αα½α αααα»αααααΉαααααΆααΆαααααΆααααααΌαααααααααααΆααααααα αααααΉαααααΆαααΆα§ααΆα ααααααα·α αα ααΆαα αααΎαα α ααα»α ααααΆαααα½αα αα»αααααΌαααααΆαααΆαααα’αααααΎαααΆαααα»αααα
- ααααααΆααααααΆαααα α»ααα ααΆα αααΎαα§ααΆα ααααα αααα»ααααααΈαααααΆα - αα»αααααΌααααα α»ααααΌαα
- αααααΈαααααΆαααΆα αααΎααα αααα»αααΈααααΆα’αΆα αΆααα αααα»ααααααααααααααΆαααααΎα - ααααααααααα·αααααα
α§ααααα .NET
.NET ααΊααα’αααα»αααΆαααααΎααΆαααΆαα½α threads ααΌα ααΆααΆαα½αααΏαααΆα αααΎααααα ααΆαα½αααΉαααααααααΈααΈαα½αα ααΆααααΆαα§αααααααααΈααΆααααα αααΎαα‘αΎααααααΆααααααΎααΆαααΆαα½ααα½ααα αααααΆααααααΈααααΆαα’ααΌααΈααΎαααααααα‘αΆα OS α αα αααααααΎααΆαααΆαα½αααΆαααΆααααα’ααΌααΈ α’αααα’αα·αααααααααααααααααααΎααααΆαααα·ααΈααΆαααααααααα»αα±ααΆα αα αααααααΎα’ααΌααΈααααα·αααααα ααΎααααΈα α»ααα ααααα·ααα½α α¬α αααΎαααΆααααααα ααΆαα αααΎαααΆαα·αα αΆαααΆα ααα ααΆααα·αααΆααΎαααααΆαααΆαααααα½αα―ααααααΆαααααΎαααααΈ ααα»ααααααααααααααα»αααααΈαααα ααΆα’αΆα ααΆαα·ααΈαααα½ααααααΎααααΈαααααααΆααααα αΆααααα·αααααΌαααΆααααααααΆααα ααααα·ααα αα α»ααααααααααΆαα’ααΌααΈα .
ααΆααααα§ααααα αααα»αααΆααααααΆααΆααα ααα»α αααααΆαααααααα·ααΈαααααα·ααΈ (APIs) αααααααααααααααααααα αα·ααααα ααααΆααΈααΈααΈ ααααΌα ααΆαααααααααΆααααααα·ααΈααΆααααΌααααααααα½ααααααΆαααααααααααα αΆααΆαα½ααααααΆααααααΉαααΌααα α»ααααα
ααΆαα αΆααααααΎααααααααα‘αΆα
Thread class ααΊααΆααααΆααααΌαααααΆααααα»ααα αααα»α .NET αααααΆααααααΎααΆαααΆαα½α threadsα α’αααααΆααααααα½αααααααΆαααααΆαααααα»αα ααααααααΆαααΈαα
- ThreadStart - ααααΆααααΆαααΆαααααα
- ParameterizedThreadStart - ααΆαα½ααααΆαααΆαααααααα½αααααααα»ααααααα
ααααα·ααΌααΉαααααΌαααΆαααααα·ααααα·αααα»ααααααααα‘αΆααααααΆααααααΎαααααΈαααααΆααααΈα α αα·ααΈααΆαααααα αΆααααααΎαα ααααα·αααΎααααα·ααΌαααααααα ParametrizedThreadStart ααααΌαααΆααααααΌααα α’ααααααααΎα αααααααα»ααααΌαααααααΌαααΆααααααΌααα αα·ααΈααΆαααααα αΆααααααΎαα ααααααΆααααααααΌαααΆαααΆα αΆαααΆα αααΎααααΈαααααααααααΆααααα»ααααα»αααΆαα½ααα ααΆααααααααΈαα ααΆαα½αα±ααααααααααΆααααΆααΆααααααΎααααααααα‘αΆαααΊααΆααααα·ααααα·ααΆαααααα αΎααααααααα‘αΆααααα½αα―αααΊααΆααααα»ααααααααΆαα αα ααΆαααααααααΆαααα ααα’αααα αα αΆα 1MB αα ααΎαααα αΎαααααΌαααΆαα’ααααααααααΆαα½α OS API α
new Thread(...).Start(...);
ααααΆαα ThreadPool ααααΆαα±αααααα·αααα’αΆααα½αα αα αααα»α .NET, thread pool ααΊααΆααααααα½ααααα·ααααααα α αΎαα’αααα’αα·αααααααα 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
ααΆαααΎααα·αααααΆααααα α»ααααααααα‘αΆα
Threads ααααααααΎααααα’ααα αααΆαααΆαα»ααΆααΈααΈααΈααΆααα’αα αα·ααααα»α .NET α’αΆα ααααΌαααΆαααΎααα αααα»ααααα’α½α Threads αα Visual Studio α αα·αααΌαααααΉααααα αΆαααααααααΆααααααααα‘αΆααα αααααααααααα·ααΈαααα·ααα αααααααΆαααααΆααααα α»α αα·ααα αααα»ααααααααααα αα ααΈαααα’αααα’αΆα ααΎααααααααα αα·αα’αΆαα·ααΆααααααααααα‘αΆαααΈαα½ααααΆααααΆαααΆααααα½α α αΎαααααΌαααΆαααααα α»ααα ααΆαααααααα‘αΆαααΆααααΆαααα½αα αααααααΎααααααααααααα·α’αΆαα·ααΆαααααααΆαα Thread α’αααα’αΆα αααααα’αΆαα·ααΆααααααααααα‘αΆα ααα OC αα·α CLR ααΉααααααΆααΆααΆαααααΆααα ααααααα αααααααααΆααααΎαααΆααααΆααααααααα‘αΆαα
αααααΆααααααΆαααΆα‘αααα·α αα ααΆα
Task Parallel Library (TPL) ααααΌαααΆαααααΆααα αααα»α .NET 4.0α α₯α‘αΌααααααΆααΊααΆαααααααΆααα·αααΆα§αααααααααΆαααααααΆααααααΎααΆαααΆαα½αα’ααααΆαα ααΌαααΆαα½ααααααααΎαα·ααΈααΆαααααα αΆααααααΌαααΆαα αΆαααα»αααΆααΆααααααααα α―αααΆααΌαααααΆααα TPL ααΊααΆααααΆαααα·α αα ααΆαααΈ System.Threading.Tasks namespace α αα·α αα ααΆαααΊααΆααΆαα’ααΌααΈααΎααααα ααΆαα½αααΉαααααααααΈααααΆααΆ C# ααΎαααα½αααΆααα·ααΈααΎαααΆαααΎααααΈααααΎααΆαααΆαα½α Tasks - async/await operatorsα ααααααα·αααΆαααααααΆαααααΎα±ααααΆα’αΆα αααααααΌαα’ααααΆα α αΆααααΌα ααΆααΆαααα αα·αααααΆααααα αααααααΎα±ααααΆα’αΆα ααααΎαα ααΆαααΌααααΈαααααααΆααα’ααααααααΆαααΆααααααΉααα·α αα½α α’αααΈααΆαααΆαααΆααααα»ααααααααααα‘αΆαααΎααααΈααααααααααα·ααΈαααααααΎαα½αααΆ αααααα·ααΈααααα·αααααααα αααααααα·ααααα·ααΆαααΌαα ααΆαααααΎααααΆαα async/await ααΊααΆαααααΆααααααααΆααα’ααααααα½α α¬ααΌααααΈααα’αααααααΆα αααΎα ααα»αααααααα»αααΉαααααΆααΆαααααααααααΈααΆαα αααα»ααααααααα½αα ααα½αα
- async ααΊβααΆβααΆαβααααααβααβαα·ααΈβααΆβαααααβαααβαααα‘ααβααΆααα·α αα βα¬βαααα
- α αΎααααα αΆαααΊααΆααααα·ααααα·αααααα αΆαααΆααα·α αα ααααα·αααΆααΆααα
ααΆααααΈαααααααα ααααα·ααααα·ααααααααα»ααααα αΆα αααα»αααααΈααΌαα (ααΆαααααΈααΎαααα) ααΉαα ααααααΆαααΆαααααα·ααααα·αα αα α»ααααααααααααααα α αΎααα αααααα Task αααα ααααΆαααααα·ααααα·ααααααΆ αα·ααααααααα‘αΆα (ααΆααα·α ααΆααΉαααΆααααααααΉαααααΌααααα»αααΆααα·ααΆαααα·ααα ααα»ααααβαα βαααβαααααβααα) ααΉαβααααβααααα·ααααα·βαα·ααΈβαααβααααααβαααα αα ααΆααααα»α .NET ααααααΆααααααααΌαααΆαα’αα»ααααααΆαααααααΌα ααααΆαα ααΉααα·ααααααααα‘αααααα·α αα αααααααα·ααΈααΆααααααααααΆαααααααααααα ααΆααααΆααααΆααααΌα αααααΆαααΆαααΈααααααααα α αΎαα’αΆα ααααΌαααΆαα’αα»ααααααΆαααααααΆα ααααα‘ααα’αΆαααααααΎααααααΆαααααα ααααΆααααΆαααααα αΆααα’αΆααααααα’αΆα αααααααΌαααΆααααααΆαα½ααααααααΎ asynΡ/await α ααααα αα·αααΎαααΆααα½αααααα»αααααΆαααααααΎ JetBrains dotPeek ααΆαα½αααΉααααααα·ααΈ Compiler Generated Code αααααΆαααΎαα
ααΌααααα‘ααααΎααααααΎααααααΆααααΆαααΎαααααΎαααΆα αα·αααααΎααααΆαα 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 object ααΉαα’αΆα ααααααααΆαααααα·ααααα·αα Task αα»ααααααΆα αΆααααααΎαααα»αααααα
αααΆαααΆααααααα α»ααααααααΊααΆααααα»αααααααααααααααα TaskScheduler α ααααΆααααα αα·αααΌαα α ααααααΆααααΌαααΆααα ααΆα‘αΎαααΎααααΈααααααααααα»αααααΆααααααααααΆααα ααα αΆααα·α αα ααΆαααααααΆαααααααααα‘αΆαα ααΆαααααΆαααΎα αα·α αα ααΆαααΉαααααΌαααΆαααααα·ααααα·ααΎαααααααα‘αΆαα αααααααΈαααα»αα
ααααα·ααααα·ααααααααα»ααααα αΆαααααΌαααΆαα’αα»ααααα αααααα·α αα ααΆααααααΆααααααΎα αααααΆααααααΆααΌααααααααααααααΆααααΈααΆ ααααα·αααΎααΆααα½α ααΉαααααΌαααΆαααααα·ααααα·αααα»αααα·ααααΌα ααααΆ (ααΆααΏααααΆααΆααααααΆαα ααΎααααα’ααααααΌα ααααΆ) ααΆααΌααα»αααααααα αΆαα
αα·ααΈααΆαααααααααΌαααΆααααααΆααααΆ async void αααααΆααααααΆααΆα’αΆα ααααΎααααα·ααααα·ααααααααα»ααααα αΆα ααα»αααααααααΌαα α ααΌαααααααΉααα·αα’αΆα αααα αΆαααΆαααααα·ααααα·ααΆαααα ααααα·αααΎαααααααα·αααααααααααΊα αΆαααΆα α ααααα·ααΈααΆαααααααααΌααααααα‘αα Task αα·αα αα·ααΈααΆααααααααααααΌαααΆααααααΆααααΆ async α αΆαααα»αααΆααααααΊααΆααΏαααααααΆααΆααα ααΆαααα½α ααΆαααααααΊααΆα’ααααααααααΆαααααΉαααα·ααΆααα α¬αα·ααΈααΆααααααααααααααααααααΎαααΆαααΎααααΎα αα·αααααα αααααΆαααα ααααα·αααΎα’αααααααΌαααΆααα·αααααΉααααααααα±ααΆαα±αααααα αΆααα αΌααααα α»ααααα ααααααΆαααααα·ααααα·ααα»ααααααα ααα»αααααααααΆααααααααααααααααα·α αααα’αααααααΌαααααΎ Task α
αα ααΎαα·α αα ααΆαααααα·ααΈααΆααααα StartNew ααΆααααααααααα·α ααααΌα ααΆααΎα’αααΈαααααααα α’αααα’αΆα α α αα·ααΈααΆααααα ConfigureAwait ααΆαα½αααΉααααΆαααΆαααααααα·ααα·α αααααΆααααααΆαααααα·ααααα·αααααΆααααΈααΆααααα αΆαααΉααααααα·ααα ααΎααα·αααααααΆαα αΆααααααααα ααα»ααααααΆαα’αααΎα α·ααααα½αα ααΆαα½αααααααΌαααΆαααααΎααΆαα·α αα αα ααααααααα·ααααααα·ααααα·αα·αααααΆαααααααΆααααΌααααααΆααααΈαααα αΆαα αααααααΆααΆαααααΆαααΈ 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
}
αααα»αα§ααΆα αααααΈαα½α ααΎααααα αΆαα±αααα·α αα ααΆααααα ααααααα·αααΆααΆααααααααΆαα α ααΌααααααα ααΎαααΉααααα‘αααα ααααΎαααΆααααααααα·α αα»αααααΆααααΆααΆααα½α α αΎα αα αΌαααΆααααααααααΆαα α ααΌαααααααααΌαααΆααα»αα αααα α§αααααααααααΆα
αα αααα»ααααααΎαααΈααΈαααΎαααΆααΆαααααααααα‘αΆαα α αα αΌαααααααααααααα·ααΈααΆαααααααααΌαααΆαααααΆα ααααα·αααα’αα·αααααΉααααααααΆαααααΎαααΆαααΆααααΆαααααααααα‘αΆα αααααΆααααΆαααααΆαααααααααααααααα·ααΈαααααΆααααααααΆααααααα»ααααααα ααα»αααααααααααΆαααααααα·αααΎααΌααααα·ααΈααΆααααααααααΎαα α ααΆααααα»ααααα αΆα α αΎαααα·ααααααΆαααααΎααααΆααααααααααΌαα±αααααααααα ααααααΆαα α ααΌααααααα·ααααααΆααααΈ αααα αΆα αααααΆαααα ααΎαααΉαααα½αααΆαααΆαααΆααααΆααα ααααααΆαα α ααΌααααααααα αΆααααααααααα·ααΈααΆαααααα’ααααΆααααααααΌαααααΆ αα·ααΈααΆαααααα’ααααΆαααααΆααΆααααα₯ααααααααα ααΎααααΈααααααΆαααααα·ααααα·ααααααΆαα αααα»ααααααααα‘αΆαα α ααΌαααααα
αα»ααα·ααααα·αα½αααααααα·ααΈααΆααααααααααΊααΆααααααααΆαααα α»ααααααα»αααααΆαα ααΆααα·αααΊααΆααα α»ααα αααα»αααΌαα’ααααΆααα αααααααΎ async/await ααΊααΆααααα½ααααααααΆαααΆαα - αα½αααααΆαα₯αα·ααΆααααΌα ααααΆαα ααΉαααΌααααααααΎααααΆααααααααα αααβαααβαααβααΎαβα’αα»ααααβααΆαβαααα αΆαβααααΆαααααβαα βαα·α αα ααΆαβαα½α ααΆαβααΎαβαααβααΎαβααααβαα βααΆ AggregateException αααβααΊα ααΎααααΈαααααααΆαααααΈααΎαααα α’αααααΉαααααΌααα·αα·αααααΎααααααα InnerException α αΎαααααααααααααααΆααααααααα½αα―ααα αααα»ααααα»αα αΆαααα½α α¬ααααΎααΆαα αΆαααα αααααΆαααα αααα½αα±αααααααααααΆαααααααα»αα αΆαααααααααΆααααααΆαααα αααα»ααα·αα C# α
α§ααΆα αααααΈααΈ αα·αα α»ααααααααααααΌαααΆααααααΆααααΆαα·αααα’αααααΆααα ααα»ααααΌα ααααΆ αα·αααΆααααα αΆααΌα ααααΆααΆααα’ααα
αα·ααΈααΆααααα WhenAny αα·α WhenAll ααΊααΆααααα½ααααα»ααααααΆααααΆααααα αΆααααα»α Tasks αα½αααΆαα»ααααα»α Tasks αα ααΆαα½α αααααΉαααΆαααα αααααα Task ααΈαααα»αααααΌαααΆααααααΆααΎαααααΌα α¬αα αααααααα½αααααΆααα’ααααΆααααα ααααΆαααααα·ααααα·αααααα½αααα
ααΆααααααααααααααα‘αΆα
αααααΆααα ααα»αααααααα ααΆα’αΆα α αΆαααΆα αααΎααααΈααααααααα αΌααααααΆααααΈααΆααΆαα αΆααααααΎαα ααΆααα·ααΈααΆα αααΎαααΎααααΈααααΎααΏααααα ααααΆαα Thread ααΆααα·ααΈααΆαααααααΈααααααΆααααααααααΉαααααΌαα αααααα ΠΈ ααα’αΆα. ααΈαα½αααΊαα·αααααΌαααΆαααααΆαα’ααααααΎααααααα αααααΆααβααΈβα α βααΆβαα βαααβα ααααα ααα‘α»αβαααβααααΎαβααΆαβααβααΆαβααααΆαβααΆβαα½α ααΆαβααΎαβαααβααΉαβααααΌαβααΆαβαααα αα ThreadAbortedException. α’αααβαα·αβααααΉαβααΆβααΆαβααΎαβαααβαααβαααβααααΌαβααΆαβαααα ααβαα βαααβαααααΎαβα’αααβα ααα½αβαααβααβααααα? α αΎααα αααααααΎαα·ααΈααα αααααΊααΆααααΆαααΆαααΆαααααααααΆααα ααααα·αααΎα’αααααααΌαααΆαααΆαααΆα CLR ααΈααΆααααααΎαααααΈααΎαααααααααααα αααα»ααααααααΆααααΆααααααΌα α’αααα’αΆα αα»αααΆαα αααα»αααΆαα α ααΌαααααα Thread.BeginCriticalRegion, Thread.EndCriticalRegion. αααααΌαααΆαα½ααααααααααα αααα»ααααα»αα α»ααααααααΊααααΌαααΆααα»ααααααΆαα α ααααααα αααααΆααα ααα»ααααα αα αααα»αααααα ααααΌαααααααααα α’αααα’αΆα ααααΎααααα»αααΆαα½αααΉαααΆαααααΆααΆαααα ααα»ααααα α»αααααααα·ααααααΆααααααααα Microsoft ααααΆααααΉαα α·ααααα·ααΈααΆαααααααααααΆαααααΆαα ααααα½ααααα·αααΆααααα αΌαααΆαα αααα»α .net coreα
αα·ααΈααΆααααα Interrupt ααΆαααααα·αααααΆαααΆαα ααΆα’αΆα ααααΆααααααααα‘αΆααααααΆαααααΈααΎαααααα½αα ThreadInterruptedException ααΆααααααα»αα’αα‘α»ααααααΆααααααα αααααααααααααα‘αΆααααα·ααα αααα»αααααΆαααΆααααα αΆαα ααΆα αΌααααα»αααααΆαααΆαααα ααααααα»ααααα½α αααααααααα αΆα WaitHandle α αΆαααα α¬αααααΆααααΈα α ααΌααααααα Thread.Sleepα
αααααΎαααΆααααΈααααααΆααα·αααααΆααΆαααΎααΊαα·αααα’αααααΆααααα·αα’αΆα ααΆααα»αααΆαα»αααΆαα αααααααααΆαααΊααααΎαα ααΆαααααααα CancellationToken αα·αααααΆαα ααααα CancellationToken. α ααα»α ααΊαααα α§ααΆα αααααααααΆαα CancellationTokenSource ααααΌαααΆααααααΎαα‘αΎα α αΎαααΆαααα’ααααααααΆααα αΆααααΆααα»ααααααααα’αΆα ααααααααααα·ααααα·ααΆααααα α αα·ααΈααΆααααα αααααα. ααΆααα CancellationToken ααα»ααααααααααααΌαααΆααααααΌααα ααααα·ααααα·ααΆαααααααα½αα―αα ααα αΆαα CancellationToken αα·αα’αΆα αα»αα ααααααα·ααααα·ααΆαααααααα½αα―αααΆααα ααα»ααααααααΆααααα’αΆα αα·αα·αααααΎαααΆααΎααααα·ααααα·ααΆααααααααΌαααΆααα»αα ααα¬α’ααα ααΆααααααααααααααα·αααΌααΈααααααΆααααΆααααα ααααΌαααΆαααααΎαα»αααΆααα»αα αα αα·ααα·ααΈααΆααααα ααααΎαα»ααααααα. ααααααααααααΉαααΎαααααΈααΎαααααα½αα TaskCelledException ααααα·αααΎαα·ααΈααΆαααααααααααααααΌαααΆαα α αα ααΎα§ααΆα ααα CancellationToken αααα»αααααΌαααΆααααα α αΎααααααΊααΆαα·ααΈααΆαααααααααααα»αααααΆαα’ααααααΎα αααααΊααΆααΆααααααα’ααΎαααααΎαααΈαα»α αααααα½αααΆαααΆαααααααααααααααα αα α ααα»α ααΆαααααααα·ααααα·ααΆαααΎααααα’αΆα ααααΌαααΆααα»αα ααα
αααααΎαααααααα αααα»ααααααΆααααΆααααααααααααααα‘αΆαααΊααΆαα α αα»αααΆα Win32 API TerminateThread α α₯αα·ααΆαααααα CLR αααααΆααααΈα α αα»αααΆαααααααα ααααΆαα·αα’αΆα ααΆααα»αααΆαα»αααΆαα αα ααΎ MSDN ααΆαααααααααααααΌαααΆααααααα’αααΈαα»αααΆααααα "TerminateThread ααΊααΆαα»αααΆααααααααααααΆααααααα½αααααααΌαααΆαααααΎαααα αααα»αααααΈααααααααααααα»αα β
ααΆαααααααα API α αΆαααα Task Based αααααααΎαα·ααΈααΆααααα FromAsync
ααααα·αααΎα’αααααΆαααααΆααααααααααΆαααααα»αααΆαααααΎααΆαααΎαααααααααααΆαα αΆααααααΎααααααΆααααΈ Tasks ααααΌαααΆαααααΆα αα·ααααααααααΆααααααααααααααΆααααααααΆααα’αααα’αα·ααααααααΆαα αααΎα αααα’αααααΉααα·αα αΆαααΆα ααααααααΆαααΆαα½α APIs α αΆαααα αααΎααα ααΆααααΆααΈααΈααΈ αα·ααααα»αααααα’ααα ααΆαααααΎααΆαα»αααααααΆαααΈα’ααΈαααΆαα ααααΆαα αΎα ααααααα»αααΆαααΆα .NET Framework ααΆαααΎαααααΎα αααααΈααΆααααα ααΊααΎααααΈαααααααΆαααα½αααΎααααααα ααααΌαα αΎαααΆααααα’αΆα ααααΎααΆα .NET ααΆαα§ααααααα½αα ααα½ααααααΆαααααααααααΌαααααα·αααΊα αΆαα αααααααααααα»ααααααα·ααΈα’ααααΆαα αΆαα αα·ααα αα·ααααααααΈα αα½ααααα»αα αααααα½αααααΊααΆαα·ααΈααΆααααα FromAsync αα TaskFactory α αααα»αα§ααΆα αααααΌαααΆαααααα αααα»ααα»ααα·ααΈααΆααααα async α αΆααααααααΆαα 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
α§αααααααααΆαααα½αααααααααααΌααα·α αΆαααΆααΊααααΆαα ααααα TaskCompletion. αα αααα»ααααααααααααα»αααΆα ααααααα αα·ααααααΆαααααααααα·ααααα·ααΆα ααΆα’αΆα ααΉαααΎααααααααΈαα·ααΈααΆααααα RegisterWaitForSingleObject ααααααΆαα ThreadPool ααααααα»αααΆααααααα’αααΈααΆαααΎα αααααααΎααααΆααααα α’αααα’αΆα αα»α APIs α’ααααΆαα αΆααααΆααααΆαααΆααααα½α αα·αααΆααααα½ααα αααα»α Tasks α
α’αααααΉααα·ααΆαααΆαααα»αααΆααα·ααΆααα½α α αΎαα’αααΈαα·ααΈααΆααααα FromAsync ααααααΆαα TaskFactory αααααΆααααααααααΆαααααααααααΆαααααα αα ααΈααα ααΎαααΉαααααΌαα αα αΆαααΈαααααααα·ααΆααααΌαααααΆαα’αα·ααααααααααΌα’ααααΆααα αααα»α .net ααα Microsoft ααΆααααααααΌααααα»ααααααα 15 ααααΆαααααααααααα αα»αααα Task-Based Asynchronous Pattern (TAP) ααΆα Asynchronous Programming Pattern (APP) ααα ααΊα’αααΈαα·ααΈααΆααααα α αΆααααααΎαααααΎα’αααΈαα½ααααα‘αααααα·α αααααα IAsync αα·ααα·ααΈααΆααααα αααα ααDoSomething αααααα½αααααΆ αα·ααααααΆαααααααα·ααααααααααααΆαααΆααααα αα·ααΈααΆααααα FromAsync ααΊααααΆααααααα’α₯αααα αα ααα»ααααααΌαααα ααΆααααΌαααΆααααα½αααα Event Based Asynchronous Pattern (EAP) αααααααααααΆααααΉαααα·ααΆααααα½αααΉαααααΌαααΆαααΎαα‘αΎααα ααααααααααα·ααααα·ααΆαα’ααααΆαααΆααααα ααα
TaskCompletionSource ααΊααα’α₯αααα αααααααΆααααΆααα»α Tasks αα·α APIs α αΆαααααααΆααααααΎαα‘αΎααα αα»ααα·αααααΌααααΉαααα·ααΆαααα ααααΉαααΆαααααΆαααΆαααααααΆααΆαααΌα ααΆααααααα ααααα»ααααααΆαααααααΆααααααααααααααα·ααΆααΆααααααααααα Task ααααΆαααΆααααα’αΆα ααααΌαααΆααααααααααααΆαααα SetResult, SetException ααΆααΎαα αα·ααΈααΆαααααααααααΆαα TaskCompletionSource α αα αααααααααααααα·ααααα·αααααα αΆαααααΌαααΆαα’αα»ααααα αααααα·α αα ααΆαααα ααΆααΉαααααΌαααΆαααααα·ααααα· α¬αααΆααααααααΆαααααΈααΎαααααα½αα’αΆαααααααΎαα·ααΈααΆααααααααααΆαα’αα»ααααα αααα TaskCompletionSource α ααααα·αααΎααΆαα αααα·αα αααΆαα ααΌααααα‘ααααΎαα§ααΆα αααααΌαααα ααα EAP API α αΆαααα½αα ααα½αααααΌαααΆααα»ααααα»α Task αααααααΎ TaskCompletionSourceα αα ααααααααααΉαααα·ααΆααααααααΎαα‘αΎα αα·α αα ααΆαααΉαααααΌαααΆαααααααα ααααΆαααΆααααααΆααααα αα α αΎααα·ααΈααΆααααααααααΆαα’αα»ααααααααα·ααααα·ααααααααα»ααααα αΆαα αα·α αα ααΆααααααΉαααααααΆαααααα·ααααα·ααααααΆα‘αΎααα·α αααααΆααααΈααΆαααα½αααααα» αααααα.
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
ααΆααα»α APIs α αΆααααΊαα·ααααααΆααα’αααααα’αΆα ααααΎααΆααααααααΎ TaskCompletionSource αααααα ααΆαααααΎααααΆαααααααΎαααααααΆααα½αα±ααα αΆααα’αΆαααααααααα»αααΆααα ααΆ APIs αααααααα ααΎ Tasks ααααα·αααΆααααΆαααααααααα‘αΆαα α αΎαααααααΈαααΌα αααααΎαα αα αΆαααΊααΆααααΆαααααα αΎαα ααα½ααααααα½αααααααΌαααΆαααααα (ααΆα αααααααα ααα½α RAM) α ααΆαααααααααα’αΆα αααααα ααΆααααΆαααΆααααα½αααααααααΎαααΆα§ααΆα ααα αααααα·ααΈααα αααααααααααα»αααααααααα·ααααΆα’αΆααΈααααααααα»αααααΆαα α αΌαααΎααα·α αΆαααΆααΈααααααΆαααααααα»ααααα»ααα·ααΆααα αααα’αα»αααααααα·α ααΌα ααΆ Long-Pollingα
ααα»ααα ααααΉαααΆααααααα·α αααααΊα α’αααααααΌαααα½αααααααΆαααΈ API α’αααΈααααΉαααα·ααΆααααα½αα ααα½ααααααΎαα‘αΎααα ααΆαααααααΆ αααααα API αααααΆααα ααα»αααα½αα ααα½ααα·αα’αΆα ααΆαααΆαααααααΉαααα·ααΆααααααααΆααα ααα»ααααα’αΆα αααα‘ααααααΆαααΆααα·αα α§ααΆα αααααααΆαααααααΊααΆ APIs ααΆααα’αααααααααΌαααΆααααααΎαα‘αΎααα ααΎααααΌααα 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 operator αααααΎααααΆαααΈα state ααΈ method α αΎααααααΊααΆααΆααααααΎα object ααααΈ αααααααΎααααα·αααααΆαα ααα»αααααααα»αααααΈαααα ααΆα’αΆα αααααΎααααα αΆααΆαα ααααΈαααα’αΆα ααΆαα·ααΈααΆααααααα½ααααααααΌαααΆαααα α ααΆααΆααΉαααΆαα ααΎααααα»ααα·ααΆαα’αααΈααΆαα α ααΌαααααααΆαααααΊα αα·αααΆααααααΆααααΆαααααα»ααα½ααα·ααΆααΈα ααααα·αααΎαα·ααΈααΆαααααααααααααααΌαααΆααααααααΆαααααααααααα»αααααΈααΆαα αααΎαααΆαααα‘ααααααααααααααααα·ααΈααΆαααααααααααα αΆαααΆααα’ααααα .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 αααααΆααααααααα»αα αααα·α αΆαααΆααΊααααΆαα αααααα·ααΈβαααααβαααβααΆααα·α αα αα·ααα·ααααααααααα»ααααααΆα αααα»αααΆααααααΆααααΆαααΎαα½α α αΎαααΆ TPL ααΆααααααααΆααααα»αααΆαααααααααααα»αααααΆααααααααααΆααααΆαα ααα αΆαααΆααα·α αα ααααααΆαααααααααααΆαα αα»αααααΆαααααααααααααααΌαααΆαααααααα αααα»αααΌαα α ααααααΆαα TaskScheduler α ααααΎαααααααααα»αααααΆααααααααα’ααααααα ααααΆααααΌαααΆαα’αΆα ααααΆααα αααα»ααααααΆαααα ParallelExtensionsExtrasαααααΎαα‘αΎαααα Microsoft ααα»αααααα·ααααααΆααααααα .NET αα ααα»ααααααααΌαααΆαααααααααααααΆαααα αα Nuget α ααΌααααα‘ααααΎααα½ααααααααααααααααα
- CurrentThreadTaskScheduler - ααααα·ααααα· Tasks αα ααΎαααααααα‘αΆααα αα α»αααααα
- LimitedConcurrencyLevelTaskScheduler - αααααα ααα½ααα·α αα ααΆααααααααΌαααααα·ααααα·αααα»ααααααααΆαααααΆααααααΆαααΆαααααα N αααααααΌαααΆαααα½ααααα αααα»α constructor
- ααΆααααααΆαα·α TaskScheduler β ααααΌαααΆααααααααΆααΆ LimitedConcurrencyLevelTaskScheduler(1) ααΌα αααααα·α αα ααΆαααΉαααααΌαααΆαααααα·ααααα·ααΆαααααΆαααααααα
- αααααα·ααΈαααααααααααΆαααΆα - α§αααααααααΎααααΆαα
αα½α ααΆαααΆα αα·ααΈααΆααααααααα»αααΆαα ααα αΆαααΆααα·α αα α ααααΆααααΆααΊααΆ ThreadPool ααΆα ααααα‘ααα αααααααΆααααα αΆααααα αααα»α .NET ThreadPool ααΊααΆααααΆαααα·αα·αααα αα½ααααααΆαααααααα·ααΈααΆααα’αα αααααΆααααααΆααΆααααα»αααΎααααααα α¬ααΆαααααΎααααΆαααα·αααααΉαααααΌααα αααα»αααααααα½ααααααααα·ααΈα’αΆα ααΆαα±ααααΆααααααααΆαααα αααα»ααααααα·ααΈααααααααα ααΆαααααα ααα ααΆααΆααΆαααααΆαααααΆααααΆαααααα»αααΆααααααΉαααΈααΌαα ααα»αααα·ααΆαααΆαααααααα αααα αααα ααααΆααΆααααααΌαααΆαααααΎααααΆαα WorkStealingTaskSchedulers ααΆα ααααα‘αααα αααα»αααααααααααααα·ααΈ αααααΆαααααΎααααΆαα ThreadPool α’αΆα ααΆαααΆααααααΆα αα·ααα·αα’αΆα ααΆααα»αααΆαα»αααΆαα - QueuedTaskScheduler - α’αα»ααααΆαα±ααα’αααα’αα»ααααααΆααα·α αα αααααααα ααΆαα αααΆαααα½αα’αΆαα·ααΆα
- ThreadPerTaskScheduler - αααααΎααααααααα‘αΆαααΆα ααααα‘αααααααΆαααα·α αα ααΆαααΈαα½αααααααααΌαααΆαααααα·ααααα·ααΎααΆα α’αΆα ααΆααααααααααααααΆαααα·α αα ααΆααααα αααΆααααααΌαααααα·αα’αΆα ααΆααα»αααΆαα»αααΆαααΎααααΈαααα ααα
ααΆαααααααΆααααα’α·αααα’α
αααααΆααααΆαααααα α»αααααΆααααα½αααα’αααΈααααααααΆααααααΆααααααΉα Tasks, Visual Studio ααΆααααα’α½α Tasks α αα αααα»ααααα’α½α ααα α’αααα’αΆα ααΎαααΎαααααΆαααΆααα αα α»αααααααααα·α αα ααΆα α αΎαααααα αααααΆααααααΌαααααααα»αααααΎαααΆαα
PLinq αα·αααααΆαααααΆαααΆα‘αα
ααααααααΈααΎ Tasks αα·αα’αααΈααααααααΆαααααα·ααΆαα’αααΈαα½αααΆ ααΆαα§ααααααα½αα±ααα
αΆααα’αΆααααααααΈαααααα
αααα»α .NETα PLinq (Linq2Parallel) αα·αααααΆαααααΆαααΆα‘ααα ααΈαα½ααααααΆααΆααΉαααααΎαααΆαααααααααΆααααααα·ααααα·ααΆα Linq ααΆααα’αααα
ααΎαααααααα‘αΆαα
αααΎαα α
ααα½ααααααααα‘αΆαα’αΆα
ααααΌαααΆαααααααα
ααΆαααααααααααααααΎαα·ααΈαααααα WithDegreeOfParallelism α ααΆα’αα»αα ααΆαα
αααΎαααΆααΉαααΆαα PLinq αα
αααα»αααααααααΆαααΎαααααααΆαα·αααΆαααααααΆααααααααααΆααα’αααΈαααααααΆααααα»αααααααααα·ααααααααααα’αααααΎααααΈαααααααΌαααΆααααααΎαααααΏααα½αα±ααααααααααΆααααααα αααααΆααα·αααααααααααααΆαααααΆααΆαααΊααΆαααΆααα α’αααααααΆααααααααΌαααΆαα α
αα·ααΈααΆααααα AsParallel ααΆαα»ααα·αα αααααααααΆαααααα·ααΈααΆααααα Linq αα·αααααΎαααΆαααΆαααααΎαααααααΆαα’αα»ααααα ααΎαααΈααααα
ααα ααΆα’αΆα
αααααΌαααααααΆααααααααα
PLinq α’αααΈααααααααααααααα·ααααααααααα’ααααααααααΎααααααΆαααΆαααΆαα α’αααα’αΆα
α’αΆααααααα
ααααΆαααα·αα·αααααααΆαααΆα‘αααααααααΌααα·ααΈααΆααααααααααΆααααΆαααααΎα‘αΎααα·αααΆααααααΆααααααΌα Foreach ααααααααΆ ααααα·ααααα·ααααα·ααα»α αα·αααααα·ααααα·ααααα·ααΌααΆα αααΎααα αααα»αααΆαα α αααΆαααΆα‘ααα ααΆαααααα·ααααα·αααααααααα‘αΆααα αα α»ααααααααΉαααααΌααααααααα αΌααααααΆαααααΆααααΌαααΆααααα ααα α ααα½ααααααααα‘αΆαα’αΆα ααααΌαααΆαααααααα ααΆαααααααααααααααααΆαα ParallelOptions ααΆα’αΆαα»αααααα α»ααααααα α’αααααα’αΆα αααααΆαα TaskScheduler αα·α CancellationToken αααααααΎαααααΎαα
ααΆαααααΎα
αα ααααααα»αα αΆααααααΎααααααα’αααααααααααααα’ααααΎα―αααΆααααααΆαααΆααααααααααα»α αα·αααααααΆαααααααα»ααααααΌαααΆααααα»αα’αα‘α»ααααααΆαααΆααααααααα»ααααααΆααααΈααΆ αααα»ααα·αααααΉαααΆααΉαααΆαααΆα αααΎααααααα α₯α‘αΌαααα αα αααααααααααα·ααΈαα·ααααα’αααααααααααα»ααααα»αααΆαα’αααααααα ααααΈααααααααααΆαααααα»αααΆ αααααααΈ 15 ααΆααα αααα»αααΉαααααααααααααααααααα’αΆααααα αααα·α αααααααα APIs α§αααααααΎαααΎα αα·αααααα ααΉαααααΌαααΆααααααααααααα αααα»αα’ααααααααααΆααα
ααα ααααΈααααα·ααααΆα:
- α’αααααααΌαααΉαααΈα§ααααααααααΆααααααΎααΆαααΆαα½ααααααααα‘αΆα α’ααααΆα αα·ααααΆαααΆα‘αα ααΎααααΈααααΎααααΆααααααΆααααα»αααααΌαααααααΎαα
- .NET ααΆαα§ααααααααααααααΆααΆα αααΎααααααΆαααααααααααΆααααα
- αα·αααααα½αααΆααΆααα’ααααΆααααα αΆααααα½ααααα»αααααααα½αααααα ααΌα ααααααΆααΏααα’αααα’αΆα ααααααααααααα·ααααααααΆα ααα»ααααααΆααα·ααΈααΎααααΈααααααα APIs α αΆαααααααα·αα αΆαααΆα αααααΉααααααα αααΎαα
- ααΆαααααΎααΆαααΆαα½ααααααααα‘αΆααααα»α .NET ααααΌαααΆαααααΆααααααααΆαα Thread αα·α ThreadPool
- αα·ααΈααΆααααα Thread.Abort, Thread.Interrupt, αα·α Win32 API TerminateThread ααΊααΆααααααααααΆαα α αΎααα·αααααΌαααΆαααααΆααααααΆααααααΎααααΆααααα αααα½ααααα·α ααΆααΆααΆααααααΎααααα»αααΆαααααΎααααααΆα CancellationToken
- ααα αΌαααΊααΆααααΆαααααΆαααααα α αΎαααΆαααααααααααααααααΆααΆαααααα·αα ααααΆαααΆαααααααααααα‘αΆααααααααα αΆαααααΉαααα·ααΆααααα½αααααααΌαααΆααααααΆαα αααααΆααααΆαααα ααΆααΆααααα½αααααΎααααΆαα TaskCompletionSource
- α§ααααα .NET αααααΆαα’αα»ααΆα αα·αααααΎααααα»ααααααΆααααααΎααΆαααΆαα½αααΆαααααααααΆ αα·αα’ααααΆα ααΊααΆαα·α αα ααΆαα
- ααααα·ααααα·αα c# async/await α’αα»αααααααα·αααααΆααααα αΆααα·αααΆααΆαα
- α’αααβα’αΆα βαααααααααβααΆαβα ααα αΆαβαα·α αα ααΆαβαα βααΌααΆααβαααααααα‘αΆαβαααβααααΎβααααΆααβαααβααΆαβααβααΈ TaskScheduler
- αα ααΆαααααααα ValueTask α’αΆα ααΆααααααααααααα»αααΆααααααΎαααααα·αααααΆα hot-paths αα·α memory-traffic
- αα·αααΌ Tasks and Threads αααα Visual Studio αααααααΌαααααααΆαααΆα αααΎααααααΆααααααααααααααΆααααΆαααααα α»αααΌααα α»αααα α¬α’ααααΆα
- PLinq ααΊααΆα§αααααααααα’αα½α ααα»ααααααΆαααα ααααΆαα·αααΆαααααααΆααααααααααΆααα’αααΈααααααα·ααααααααααα’ααααα ααα»ααααααΆα’αΆα ααααΌαααΆααα½ααα»ααααααααΎααααααΆααααα αα
- αα βααΆαβααΆβααααβαααβ¦
ααααα: www.habr.com