MS_AsyncAwait - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- æ»ãïŒéåæåŠçïŒ
-
async/await ã®ç»å Žã§ããã«ãã¹ã¬ããåŠçãšããŠå®è£ ããªããŠãã
éåæåŠçãåæååŠçãšãã»ãŒå€ãããªãèšè¿°ã§å®¹æã«å®è£ å¯èœã«ãªã£ãã -
await ã®æå³ã¯ã
- ã¹ã¬ãããæ¢ãããã³ããããã³ã°ã§
- éåæããåæã«åŸ©åž°ãã
ãšããæå³ãããã
-
å®éãasync/await ã¯ããããåããããã
-
ã¹ã¬ããã Windows ã¡ãã»ãŒãžã³ã°ãã¥ãŒã§ Task åãããã
ææãããããã³ããªãšã³ããã£ãã»ãã«ãã¿ã¹ã¯(Win3.1)ã®ãããªã€ã¡ãŒãžã -
ãããããã®å®æ ã¯ãšãŠãè€éïŒè©³ããã¯ã³ãã©ãåç §ïŒã
- å éšãã©ãåããŠããã詳ããææ¡ããªããšã·ã¹ãã ã¯å®å®ããªãã
- äžèº«ãã·ãã«ãªçè§£ããŠäœ¿çšããŠãã人ãå°ãªãã®ã§æ³šæãå¿ èŠã
-
è£è¶³ïŒäžèšã§ãããšãç¶ç¶ã®åå²ãïŒ: async/await ã®æ¬è³ªã¯ã
ã³ã³ãã€ã©ãã¡ãœãããã¹ããŒã ãã·ã³ã«æžãæããããšã«ããããæžããã³ãŒãã var a = await FooAsync(); Console.WriteLine(a); ãã³ã³ãã€ã©ãçæãããã®ã â FooAsync() ãåŒã¶ â¡ ãŸã çµãã£ãŠããªããã°ããç¶ãããã³ãŒã«ããã¯ãšããŠç»é²ã㊠return ïŒïŒããã§ã¹ã¬ããã¯è§£æŸãããïŒ â¢ å®äºãããããç¶ããïŒConsole.WriteLineïŒãå®è¡ãããåæãããã³ããªãšã³ããã£ãã»ãã«ãã¿ã¹ã¯ã®ãããªã€ã¡ãŒãžããš
èšã£ãŠããã®ã¯ç確ã§ãOS ãã¹ã¬ãããæšªåãããã®ã§ã¯ãªãã
awaitã®äœçœ®ã§ããã°ã©ã åŽãèªçºçã«å¶åŸ¡ãææŸãç¹ãåãã§ãããéèŠãªåž°çµ:
awaitã¯åŸ ããªãã
ãã®å Žã§ return ããŠãç¶ããåŸã§å®è¡ããã
ã ããã¹ã¬ããã空ããã¹ã±ãŒã©ããªãã£ãäžããã
äž»ã«ãéåæåŠçïŒâ 䞊ååŠçïŒãç°¡åã«ïŒåæåŠççã«ïŒå®è£ ããããã«å°å ¥ãããã
-
UI ã¹ã¬ããããã®ãµãŒãåŒåºã®ãã³ã°ã¢ããã鲿¢ããããã«äœ¿çšãããã
-
ãŸãã¯ãå éšçã«ã¯ãUI ã¹ã¬ãããããæéã®ãããããã¯ã°ã©ãŠã³ãåŠç
ïŒãããã¯ãŒã¯ ãã€ã³ããŸã㯠I/O ãã€ã³ãã®åŠçïŒãåé¢ããã -
Web ãµãŒãã®ã¹ã¬ããæ¯æžãé²ãéåæ Controllerãªã©ã«ãå¿çšãããŠããã
-
䞊åå®è¡åŠçãå®è£ ããããã®åºç€ã§ã¯ãªãã
-
Fire & Forgetã Task.WhenAll ã§äžŠåå®è¡åŠçãå®è£ ã§ãããã
awaitãTask.Wait() ã® "åŸ ã¡åãã" ãŸã§ãã»ããã«ãªã£ãŠããä»çµã¿ãªã®ã§ã
ããããã䞊åå®è¡åŠçãå®è£ ããããšã«ç¹åããåºç€ã§ã¯ãªãããšã«æ³šæããã
ïŒéåæã¿ã¹ã¯ãäœæããŠåŸ ã€åŠçãåæçã«æžããä»çµã¿ãšèããã¹ãããïŒ -
䞊åå®è¡åŠçãå®è£ ããå Žåã¯ãThread ããThreadPool ã䜿çšããã°ã€ã€ã
-
è£è¶³ïŒãéåæ â 䞊åãã®èŠç¹ïŒ: åæãç¹°ãè¿ã匷調ããŠããéãã
ãããæå€§ã®èª€è§£ãã€ã³ãã§ããã
éåæïŒasync/awaitïŒ äžŠåïŒParallel / ThreadïŒ ç®ç åŸ ã¡æéã«ã¹ã¬ãããè§£æŸ CPU ã䜿ãåã 察象 I/O ããŠã³ãïŒDBãHTTPããã¡ã€ã«ïŒ CPU ããŠã³ãïŒèšç®ïŒ ã¹ã¬ãã ãããæžãïŒ1 æ¬ãèŠããªãããšãããïŒ ã³ã¢æ°ã ã䜿ã 代衚 await httpClient.GetAsync()Parallel.ForãTask.Runãasync ã¯éãããããã®éå ·ã§ã¯ãªããã
1 ä»¶ã®åŠçã¯ããããã¹ããŒã ãã·ã³ã®ã¶ããããã«é ããªãã
éããªãã®ã¯**åæã«æããæ°ïŒã¹ã«ãŒãããïŒ**ã§ãããçŸåšã®äžŠååŠçã®éå ·ã¯æ¬¡ã®éãã
çšé ææ®µ CPU ããŠã³ãã®åå² Parallel.For/Parallel.ForEachéåæåŠçã®äžŠå床å¶åŸ¡ Parallel.ForEachAsyncïŒ.NET 6+ïŒè€æ°ã®éåæãåŸ ã¡åãã Task.WhenAllçã®äžŠå ThreadïŒçŸåšã¯ã»ãŒäœ¿ããªãïŒãªã
Task.Runã¯ã䞊åãåŽã®éå ·ã§ããã
I/O åŸ ã¡ãTask.Runã§å ãã®ã¯ç¡æå³ïŒãããæå®³ïŒã§ããã
async/await ã®ç»å Žã§ãéåæåŠçãåæååŠçãšãã»ãŒå€ãããªãèšè¿°ã§å®¹æã«å®è£ å¯èœã«ãªã£ãã
-
async ã§ä¿®é£Ÿãã Task ãè¿ãéåæã¡ãœãããããawait ã¹ããŒãã¡ã³ããä»äžããŠåŒã³åºãã
-
è¥ããã¯ãTask.Run() ã§å®è¡ããŠãTask.Wait() ã§åŸ ã¡åãããã
ãããããããã°ã®æã¯éåæã§å®è¡ãããŠããããšãæèããå¿
èŠãããã
ïŒããããããªãç¹æ®ãªãåæã³ã³ããã¹ãæ¯ã«åäœã倧ããç°ãªããïŒ
-
éåæåããã®ãã³ããããã³ã°ã®åŸ©åž°ã«ã¯åæã³ã³ããã¹ãã䜿çšãããã
-
åæã³ã³ããã¹ãã«ã¯ Windows ã¡ãã»ãŒãžã³ã°ãã¥ãŒãThreadPool ãªã©ãããã
-
ä»çµã¿ã®è©³çްã«ã€ããŠã¯ã³ãã©ãåç §ã
async/await ã¯ãTAPïŒTask-based Asynchronous PatternïŒã®æ¹åŒã§å®è£ ãããŠããã
async/await ã¯ã
- ã¡ãã»ãŒãž(çªå·)ã®ãããªå¶çŽã®ããåçŽåºå®é·å€ã®ãã¥ãŒã§ã¯ãªãã
å®è¡ã³ãŒãã®ä»»æã®ã³ãŒãæçãã®ãã®ããã¥ãŒïŒåæã³ã³ããã¹ãïŒã䜿çšããŠç¹ãã§ããã - .NET 3.5 çšã® async/await äºæ NuGet ããã±ãŒãžã§ã¯ã
.NET 4 ã® Task äºæã¯ã©ã¹ããå éšã BeginInvoke çã§å®è£ ããŠãasync/await ã䜿ããããã«ããŠããã
è£è¶³ïŒéåæãã¿ãŒã³ã®äžä»£ïŒ: .NET ã®éåæã«ã¯ 3 äžä»£ããã
äžä»£ åç§° 圢 1 APMïŒAsynchronous Programming ModelïŒ BeginXxx/EndXxx2 EAPïŒEvent-based Asynchronous PatternïŒ XxxAsync+XxxCompletedã€ãã³ã3 TAPïŒTask-based Asynchronous PatternïŒ Task/Task<T>ãè¿ãçŸåšã¯ TAP ã®ã¿ã䜿ããAPM / EAP ã¯æ¢å API ã®äºæã®ããã«æ®ãã
async/await ã®å€«ã ã®æå³ã
-
async 修食å
async ã¯ãåŒã³åºãå ãšåãåæã³ã³ããã¹ãã§å®è¡ãããããšã瀺ãã -
await æŒç®å
async ã await ãããšãã¹ã¬ãããæ¢ããã«åæã³ã³ããã¹ãã§åæããã
ãã®åäœã¯æ³åãé£ãããå ·äœçã«ã¯ã
- åãåæã³ã³ããã¹ãïŒWindows ã¡ãã»ãŒãžã³ã°ãã¥ãŒïŒã«
- ã³ãŒã«ããã¯ãé çªã«äžŠã¹ãïŒControl.BeginInvoke() çãªïŒã
ãšããã€ã¡ãŒãžã
-
ã»ã»ã»çµå±ãAPMãEAP ãšåãæè¡ïŒåæã³ã³ããã¹ãïŒã䜿ã£ãŠããã
-
ãªããåæã³ã³ããã¹ãã®çš®é¡ã«ãã£ãŠãåããç°ãªãã
-
åæã³ã³ããã¹ãã¯ãã¥ãŒçãªãã®ã§å®è£ ãããŠããã
äŸãã°ãåè¿°ã®ã- Windows ã¡ãã»ãŒãžã³ã°ãã¥ãŒã
- ThreadPool
- I/O å®äºããŒã
- , etc.
-
ãªã®ã§ãèšèå°»ã ãã§åäœãæ³åãé£ãã
å©çšã®éã¯æ³šæãå¿ èŠã«ãªã£ãŠããã
-
ç§»è¡ã¡ã¢ïŒ
async修食åã®æ£ç¢ºãªæå³ïŒ: åæã®
ãasync ã¯ãåŒã³åºãå ãšåãåæã³ã³ããã¹ãã§å®è¡ãããããšã瀺ãã
ã¯ãçµæãšããŠã®æåãè¿°ã¹ããã®ã ãã
async修食åèªäœã«ã¯ãã®æå³ã¯ãªãç¹ãè£è¶³ããŠããã
asyncãè¡ãã®ã¯ã次㮠2 ã€ã ãã§ããã
- ã¡ãœããå ã§
awaitã䜿ããããã«ãã- ã³ã³ãã€ã©ã«ã¹ããŒã ãã·ã³ãžã®æžãæããæç€ºãã
ãåãåæã³ã³ããã¹ãã«æ»ããã®ã¯
awaitåŽã®æ¢å®åäœã§ããã
ConfigureAwait(false)ã§ç¡å¹åã§ããïŒåŸè¿°ïŒããŸãã
asyncãä»ããŠãã¡ãœããã¯ãã®å Žã§ã¯éåæã«ãªããªãã
asyncã¡ãœããã¯åŒã³åºããããããŸãåæçã«å®è¡ãããã
æåã®ãæªå®äºã®awaitãã«å°éããŠåããŠåŒã³åºãå ã«æ»ãã
awaitïŒTask.RunïŒãåãç®ãšããŠã
ããã°ã©ããæèããŠæéã®ãããããã¯ã°ã©ãŠã³ãåŠç
ïŒãããã¯ãŒã¯ ãã€ã³ããŸã㯠I/O ãã€ã³ãã®åŠçïŒãåå²ããã
- await åã®åŠçã¯ãã©ã¢ã°ã©ãŠã³ãçã«å®è¡ãããã
- await ã§åŒã³åºãéåæã¡ãœããã¯ããã¯ã°ã©ãŠã³ãçã«å®è¡ãããã
- await åŸã®åŠçã¯ãã³ãŒã«ããã¯ãšããŠå®è£
ããã«ãã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ããã
- å³å¯ã«èšããšãã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ã§ã¯ãªãã
ããã°ã©ã ã®ã³ãŒãäžãéåæåŠçã®åŸç¶åŠçã«åŸ©åž°ããã - äŸãã°ãéåæ Controllerã®éåæåŠçã®åŸç¶åŠçã¯ã
- éåæã¹ã¬ããåŽã§å®è¡ãããæåŸã«ãªã¯ãšã¹ããåãä»ããã¹ã¬ããã«ãã€ã³ããããã
- ãã®åäœã¯ãã·ã¹ãã çã«ã¯ããã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ãããšã¯èšããªãã
- å³å¯ã«èšããšãã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ã§ã¯ãªãã
-
Task.Run åã®åŠçã¯ãã©ã¢ã°ã©ãŠã³ãçã«å®è¡ãããã
-
Task.Run() ã§åŒã³åºãéåæã¡ãœããã¯ããã¯ã°ã©ãŠã³ãçã«å®è¡ãããã
-
Task.Wait() åŸã®åŠçã¯ãã³ãŒã«ããã¯ãšããŠå®è£ ããããŠããã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ããã
-
Task.Wait ãåŒã°ãããšã¹ã¬ãã㯠Task ãçµãããŸã§åŸ æ©ããã
-
ãããã®åãã®è©³çްã¯ãåæã³ã³ããã¹ãã«ãã£ãŠç°ãªã£ãŠããã
-
ãŸããTask.Wait ã䜿çšãããšãåæã³ã³ããã¹ãäžã
å®è¡ããéåæ Task ã®åã«ãTask.Wait ãå²ã蟌ããšãããããã¯ã«ãªã£ããããã
Fire & Forgetã®å Žåãæ»ãå€ã¯äžèŠã
Awaitableã®å Žåã
-
æ»ãå€ã®ç¡ãéåæã¡ãœãããå®è£ ããå ŽåãTask åã®æ»ãå€ãå¿ èŠã
-
åºæ¬çã«ãreturn ãæžãå¿ èŠã¯ãªãã
-
ããããéåæã¡ãœããå ã§éåæåŠçãåŒã³åºããªãå Žåã
Task.FromResultã§ãå®äºç¶æ ã® Task ãçæãã return ãæžãå¿ èŠãããã
await Task.FromResult(0);
await Task.FromResult(default(object));Awaitableã®å Žåã
-
T åã®æ»ãå€ã®æãéåæã¡ãœãããå®è£ ããå ŽåãTask<T> åã®æ»ãå€ãå¿ èŠã
-
æ»ãå€ã¯ Task<T> åã ããawait ããåŸãT ã®åã®å€ã return ããããã«å®è£ ããã
int ret = await XXXXAsync();
return ret;- ããããéåæã¡ãœããå
ã§éåæåŠçãåŒã³åºããªãå Žåã
Task.FromResultã§ãå®äºç¶æ ã® Task<T> ãçæãã return ãæžãå¿ èŠãããã
await Task.FromResult(new T());Task.FromResult ã䜿çšãããšãå®äºç¶æ ã® Task ãçæããããšãã§ããã
-
以äžã®ãããªã±ãŒã¹ã§å©çšããã
- æ»ãå€ã® Task ãé·ãã³ãŒã ãã¹ãå®è¡ããããšãªããçŽãå®äºããæ¡ä»¶ã«åèŽããå Žå
- ã€ã³ã¿ãŒãã§ã€ã¹äžã¯ Task ãè¿ãããã¡ãœããå ã§éåæåŠçãåŒã³åºããªãå Žå
-
詳现ã«ã€ããŠã¯ãäžèšãåç §ã®ããšã
- Task.FromResult(TResult) ã¡ãœãã (System.Threading.Tasks)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.tasks.task.fromresult - c# - If my interface must return Task what is the best way to have a no-operation implementation? - Stack Overflow
https://stackoverflow.com/questions/13127177/if-my-interface-must-return-task-what-is-the-best-way-to-have-a-no-operation-imp
- Task.FromResult(TResult) ã¡ãœãã (System.Threading.Tasks)
è£è¶³ïŒçŸåšã®æžãæ¹ïŒææ°åïŒ: åæã®
ãéåæåŠçãåŒã³åºããªãã¡ãœãããã®æžãæ¹ã¯ãçŸåšã§ã¯æ¹åãããŠããã// åæã®æžãæ¹ïŒasync ãä»ããŠãç¡é§ã« await ããïŒ public async Task DoAsync() { await Task.FromResult(0); } // çŸåšã®æžãæ¹ïŒasync ãä»ãããå®äºæžã¿ã¿ã¹ã¯ãè¿ãã ã public Task DoAsync() { return Task.CompletedTask; } public Task<int> GetAsync() { return Task.FromResult(42); }
asyncãä»ãããšã¹ããŒã ãã·ã³ãçæãããããã
äžã§awaitããªããªãä»ããªãæ¹ãéãã確ä¿ãæžãã
çšé 䜿ããã® æ»ãå€ãªãã®å®äºæžã¿ Task.CompletedTaskïŒ.NET 4.6+ïŒæ»ãå€ããã®å®äºæžã¿ Task.FromResult(v)äŸå€ãè¿ã Task.FromException(ex)ãã£ã³ã»ã«æžã¿ Task.FromCanceled(token)åæå®äºãå€ãé«é »åºŠåŠç ValueTask<T>ïŒã¢ãã±ãŒã·ã§ã³ãé¿ããïŒ
ValueTask<T>ã¯ãã»ãšãã©åæçã«å®äºãããã
ããŸã«éåæã«ãªããåŠçïŒãã£ãã·ã¥ ããããªã©ïŒã§
Taskã®ç¢ºä¿ã³ã¹ããé¿ããããã®åã§ããã
ãã ã2 å await ã§ããªãçã®å¶çŽãããããã
å ¬é API ã®æ¢å®ã¯Taskã®ãŸãŸã§ããã
-
Task ã®å®è¡ãå®äºããããåŸ æ©ããã«ã
ãã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ãã颚ãªåããèŠããã- await éåæã¡ãœãã()
- await Task.Run()
-
await æŒç®åã®äœ¿ãæ¹
- éåæã¡ãœãããåŒã³åºããšãã«ãawait æŒç®åãå©çšããã
- ã¡ãœããå ã§ await æŒç®åãå©çšããå Žåãasync 修食åã§ã¡ãœããã修食ããã
- await æŒç®åã¯ãasync 修食åã®ä»ãã¡ãœããã®äžã§ïŒã€ä»¥äžèšè¿°ã§ããã
-
Task.Run() ã¡ãœãã
- éåæã¡ãœãããå®è¡ã㊠TaskãTask<TResult> ãè¿ãã
-
Task.Wait()
- TaskãTask<TResult> ã®å®è¡ãå®äºãããŸã§åŸ æ©ããã
- async/await ãšç°ãªããåæã³ã³ããã¹ãã§åæããã
åŸ æ©ïŒãããã¯ïŒããåŸã«ãã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ããã
-
Task.WhenAll()
- ã¡ãœããã§è€æ°ã®ã¿ã¹ã¯ãåŸ æ©ããã¿ã¹ã¯ãååŸããã
- ãã® Task ã Task.Wait() ãããš Task æ¯ã®
äŸå€ã AggregateException åãšããŠååŸå¯èœã
è£è¶³ïŒäŸå€ã®åãåºããæ¹ãéãïŒ:
Task.WhenAllã¯ã
åŸ ã¡æ¹ã«ãã£ãŠåãåããäŸå€ã®æ°ãå€ãããvar t = Task.WhenAll(t1, t2, t3); // â await â æåã® 1 ã€ã®äŸå€ã ãã throw ããã await t; // â¡ å šéšãèŠãããªããTask ããåãåºã try { await t; } catch { foreach (var e in t.Exception.InnerExceptions) Log(e); }
awaitã¯AggregateExceptionããã»ã©ããŠãæåã®äŸå€ãæãã
ïŒåæåŠçãšåãæžãå³ã«ããããã®ä»æ§ïŒã
å šä»¶ãæ±ãããå Žåã¯äžèš â¡ ã®ããã«Task.ExceptionãèŠãããŸãã
WhenAllã¯äžéšã倱æããŠããå šéšãçµãããŸã§åŸ ã€ã
ã1 ã€ã§ã倱æãããå³åº§ã«æã¡åããããå Žåã¯
CancellationTokenSourceãšçµã¿åãããã
-
[.NET Framework 4/4.5][C# 5] éåæã§åãããžãã¹ããžãã¯ãäœã
: biac ã® ãããããããããã¯å¹žããªæ¥ã @nifty
http://bluewatersoft.cocolog-nifty.com/blog/2011/12/net-framework-4.html -
Task.Start()ãTask.Factory.StartNew()ãTask.Run()
- Task ã¯ã©ã¹ãš TaskFactory ã¯ã©ã¹
http://www.kanazawa-net.ne.jp/~pmansato/parallel/parallel_taskfactory.htm - Task.Start()ãšTask.Run()ãšTask.Factory.StartNew()ã®éã - From Full To Free
http://fromfulltofree.blog.fc2.com/blog-entry-7.html
- Task ã¯ã©ã¹ãš TaskFactory ã¯ã©ã¹
-
[éèš] ã¹ã¬ãã ããŒã«ãšã¿ã¹ã¯
C# ã«ããããã°ã©ãã³ã°å ¥é | ++C++; // æªç¢ºèªé£è¡ C
http://ufcpp.net/study/csharp/misc_task.html -
Provide an asynchronous version method for call the B-layer
from the action method of asynchronous controller.
· Issue #216 · OpenTouryoProject/OpenTouryo
https://github.com/OpenTouryoProject/OpenTouryo/issues/216
ããã§ã¯ã
- ãéåæã¡ãœããã®çš®é¡ããš
- ãåæã³ã³ããã¹ããã®
çµã¿åããã«ãã£ãŠãawait åŸã®åŠçãã
ã©ã®ããã«å®è¡ãããã®ãã«ã€ããŠèª¬æããã
- åè
- async/awaitãšåæå®è¡å¶åŸ¡ | ++C++; // æªç¢ºèªé£è¡ C ããã°
https://ufcpp.wordpress.com/2012/11/12/asyncawait%E3%81%A8%E5%90%8C%E6%99%82%E5%AE%9F%E8%A1%8C%E5%88%B6%E5%BE%A1/- An other world awaits you
http://www.slideshare.net/ufcpp/an-other-world-awaits-you
- An other world awaits you
- async/awaitãšåæå®è¡å¶åŸ¡ | ++C++; // æªç¢ºèªé£è¡ C ããã°
éåæã¡ãœããã«ã¯ã2 çš®é¡ããã
-
Fire & Forget
æ»ãå€ã void ã®ã¡ãœãã -
Awaitable
æ»ãå€ã TaskïŒããã㯠Task<T>ïŒã®ã¡ãœãã
éåæã¡ãœããã§ã return æãæžãå¿ èŠãç¡ãã
æ»ãå€ã void ãªã®ã§éåæä»¥éããã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ããªãã
- éåæåŒã³åºãã§æãã£ã±ãªãå Žåã
- å ·äœçã«ã¯ãGUI ã¢ããªã±ãŒã·ã§ã³ã®ã€ãã³ãã»ãã³ãã©ã«é©çšããå Žåã
- äžèšä»¥å€ã®çšéã§ã®å©çšã¯æå³ããªãããããåå ã«ãªãã®ã§éæšå¥šã
è£è¶³ïŒ
async voidãå±éºãªçç±ïŒ: åŸè¿°ã®ã¬ã€ãã©ã€ã³ãšãéãªããã
async voidã¯åã«äžäŸ¿ãªã®ã§ã¯ãªããå±éºã§ãããâ äŸå€ãææã§ããªã â try-catch ã§å²ãã§ãæãŸããªã â åæã³ã³ããã¹ãã«çŽæ¥æããããããã»ã¹ãèœã¡ã â¡ å®äºãåŸ ãŠãªã â ãã¹ãã§ããªããçµäºåŠçãšç«¶åãã ⢠åŒã³åºãåŽããçµãã£ããããç¥ãææ®µãäžåãªãâ ãæãéãã
async TaskãªãäŸå€ã¯ Task ã«æ ŒçŽããããã
async voidã§ã¯ãã£ããããå ŽæããªããŸãŸ
ã¹ã¬ãã ããŒã«ã«æããããæªåŠçäŸå€ãšããŠããã»ã¹ãçµäºãããã// å±éºïŒäŸå€ã¯ããã§ã¯æãŸããªã try { FireAndForget(); } catch { /* å°éããªã */ } async void FireAndForget() { throw new Exception(); }ã€ãã³ã ãã³ãã©ãŒä»¥å€ã§ã¯çµ¶å¯Ÿã«äœ¿ããªãã
ã©ãããŠãæãã£ã±ãªãã«ãããå Žåã¯ã
async Taskã«ããŠãåŒã³åºãåŽã§æç€ºçã«äŸå€ãæ¡ãã_ = DoAsync().ContinueWith(t => Log(t.Exception), TaskContinuationOptions.OnlyOnFaulted);
éåæã¡ãœããã¯ãTaskãTask<T> ããªã¿ãŒã³ããã
æ»ãå€ã TaskïŒããã㯠Task<T>ïŒãªã®ã§ãawait æŒç®åã Wait() ã¡ãœãã
以éã«å®è£
ãããéåæä»¥éããã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ããã
- éåæåŒã³åºãã®åŒã³åºãå
ã§
- await ã§ãéåæä»¥éããã©ã¢ã°ã©ãŠã³ãã«åŸ©åž°ãããå Žåã
- Task.Wait() ã§åŒã³åºãå ãéåæã¡ãœããã®å®äºãåŸ æ©ããå¿ èŠãããå Žåã
å®è¡ç°å¢ã«ãã£ãŠæã€åæã³ã³ããã¹ãã®çš®é¡ãç°ãªãã
GUI ã¢ããªã±ãŒã·ã§ã³ã§ã®åæã³ã³ããã¹ãã¯
ãWindows ã¡ãã»ãŒãžã³ã°ãã¥ãŒïŒControl.Invokeã.BeginInvoke ã§äœ¿ãïŒãã«ãªãã
-
Fire & Forget
GUI ã¢ããªã±ãŒã·ã§ã³ã® await ã®æ¬¡ã®åŠçã¯ã
åæã³ã³ããã¹ãã® Control.BeginInvoke ã«ãã£ãŠã
UI ã¹ã¬ããäžã§ã·ãŒã±ã³ã·ã£ã«ã«å®è¡ãããã -
Awaitable
該åœãªãïŒControl.Invoke ã§ã¯ïŒ
Console ã¢ããªã±ãŒã·ã§ã³ã§ã®åæã³ã³ããã¹ãã¯ãnullãã«ãªãã
-
Fire & Forget
éæšå¥šïŒThread ããThreadPool ã䜿çšããã°ã€ã€ïŒ -
Awaitable
- Console ã¢ããªã±ãŒã·ã§ã³å ã® await ã®æ¬¡ã®åŠçãå®è¡ãããã¹ã¬ããã¯äžæã§ã¯ãªããªãã
- ãã ããåŠçèªäœã¯ãïŒèšè¿°ããé ã«ïŒã·ãŒã±ã³ã·ã£ã«ã«å®è¡ãããã
Task.Run ã䜿çšããå Žåã®åæã³ã³ããã¹ãã¯ã
ãã«ãã¹ã¬ããç°å¢äžã®ãThreadPoolãã«ãªãã
-
Fire & Forget
éæšå¥šïŒThread ããThreadPool ã䜿çšããã°ã€ã€ïŒ -
Awaitable
- Task.Run å ã® await ã®æ¬¡ã®åŠçãå®è¡ãããã¹ã¬ããã¯äžæã§ã¯ãªããªãã
- äžã€ãTask.Run å ã® await ã®æ¬¡ã®åŠçã¯ãUI ã¹ã¬ããã«æ»ããªããªãã
- ãã ããåŠçèªäœã¯ãïŒèšè¿°ããé ã«ïŒã·ãŒã±ã³ã·ã£ã«ã«å®è¡ãããã
ASP.NET ã¢ããªã±ãŒã·ã§ã³ã§ã®åæã³ã³ããã¹ãã¯
ãã«ãã¹ã¬ããç°å¢äžã®ãSystem.Threading.SynchronizationContext.Currentãã«ãªãã
-
Fire & Forget
éæšå¥šïŒThread ããThreadPool ã䜿çšããã°ã€ã€ïŒ -
Awaitable
- ASP.NET ã¢ããªã±ãŒã·ã§ã³ã® await ã®æ¬¡ã®åŠçãå®è¡ãããã¹ã¬ããã¯äžæã§ã¯ãªããªãã
- ãã ããåŠçèªäœã¯ãïŒèšè¿°ããé ã«ïŒã·ãŒã±ã³ã·ã£ã«ã«å®è¡ãããã
- HttpContext çã®ä¿æãéåæåŠçãå šãŠçµãããŸã§ãã¬ã¹ãã³ã¹ããªãããç£èŠ
- æçµçã«çµæã¯ããªã¯ãšã¹ããåãä»ããã¹ã¬ããã«ãã€ã³ããããã
詳ããã¯ãéåæ Controllerãåèã«ããã
ãã®èŸºã®
- asp.net mvc - MVC Action Filters Collection was modified;
enumeration operation may not execute - Stack Overflow
http://stackoverflow.com/questions/29429526/mvc-action-filters-collection-was-modified-enumeration-operation-may-not-execut
ã¹ã¿ãã¯ã»ãã¬ãŒã¹ãèŠããšã
- ãSynchronizationContextããš
- ãAsyncControllerActioninvokerãã¯
åãäºããããšè§£ãã
ãªããæããããããã®åæã³ã³ããã¹ãã¯ã
I/O å®äºããŒãïŒIOCPïŒ= ãã³ããããã³ã° I/O ã§ãããšæãããã
- Can ASP.NET MVC's AsyncController be used to service large number of
concurrent hanging requests (long poll)? - Stack Overflow
http://stackoverflow.com/questions/4982882/can-asp-net-mvcs-asynccontroller-be-used-to-service-large-number-of-concurrent
è£è¶³ïŒASP.NET Core ã§ã¯åæã³ã³ããã¹ããç¡ãïŒææ°åïŒ: æ¬ç¯ã¯
**.NET Framework æä»£ã® ASP.NETïŒSystem.WebïŒ**ãåæãšããŠããã
ASP.NET Core ã§ã¯ç¶æ³ã倧ããå€ãã£ãã®ã§ãèŠç¹ãè£ãã
ASP.NET (System.Web) ASP.NET Core åæã³ã³ããã¹ã AspNetSynchronizationContextããnullïŒååšããªãïŒ awaitåŸã®ã¹ã¬ããå ã®ãªã¯ãšã¹ã ã¹ã¬ããã«ãã€ã³ã ThreadPool ã®ä»»æã®ã¹ã¬ãã HttpContextåæã³ã³ããã¹ããæã¡åã IHttpContextAccessorïŒAsyncLocalïŒ.Result/.Wait()ãããããã¯ãã ãããããã¯ã¯ããªãïŒãæ¯æžããïŒ ConfigureAwait(false)å¿ é çŽ äžèŠïŒå¹æããªãïŒ ASP.NET Core ã§åæã³ã³ããã¹ããæ€å»ãããããšã«ããã
æ¬ããŒãžã詳述ããŠãããããããã¯åé¡ã®å€ãã¯
æ§é çã«è§£æ¶ããããã ã
.Result/.Wait()ãå®å šã«ãªã£ãããã§ã¯ãªãã
ãããããã¯ã¯ããªããªã£ããã
ã¹ã¬ããã 1 æ¬å æããŠåŸ ã€ããã
è² è·ãé«ãŸããšã¹ã¬ãã ããŒã«æ¯æžãèµ·ããã
åæçã«ãããã¯ããŠã¯ãªããªããšããçµè«ã¯å€ãããªãããªããåæã³ã³ããã¹ããæ®ãã®ã¯äž»ã« UI
ïŒWPF / WinForms / MAUIïŒã§ããã
ããã§ã¯æ¬ç¯ã®è°è«ãä»ãæå¹ã§ããã
- GUI 以å€ã®åæã³ã³ããã¹ãã§ Fire & Forget ãå®è¡ããå ŽåïŒéæšå¥šïŒãã
- Task.WhenAll ã§è€æ°ã® Task ã Task.Wait() ããå ŽåïŒThreadPool ã§å®è¡ãããïŒã§ã¯ã
䞊åå®è¡ãå§ããã®ã§ã
ç¹ã«ãConsole ã¢ããªã±ãŒã·ã§ã³ã®åæã³ã³ããã¹ãïŒnullïŒã®äžã§ã¯ã
æ°èŠã«åæåŠçã®å®è£
ãå¿
èŠã«ãªãããšãããã
async/await ã¯éåæåŒã³åºãã§æãã£ã±ãªããåŸã«ã
åæã³ã³ããã¹ãã«ããåæãããæ¹åŒã®ãããåæãããŸãèæ
®ããŠããªããã
åæã³ã³ããã¹ãã«ãã£ãŠã¯ãåæãè¡ãå¿
èŠãããããã以äžã«æ³šæããã
ã¹ã¬ããã䜿çšããåŠçãèšè¿°ããªããã
åå²ãããã¿ã¹ã¯ã¯ã
- åäžã¹ã¬ããã§åäœããããšã
- å¥ã¹ã¬ããã§åäœããããšãããã
ãã®ãããäžé£ã®åŠçãïŒåå²ãããã¿ã¹ã¯ãïŒã
- ç°ãªãã¹ã¬ããã§å®è£ ãããä¿èšŒã¯ç¡ãã
- åãã¹ã¬ããã§å®è¡ãããä¿èšŒãç¡ãã
åŸã£ãŠãã¹ã¬ããåæã® lock çã¯ç¡æå³ã
åŸæ¥ã®ã¹ã¬ããåæããŒã«ãããã¯äœ¿çšäžå¯ã
æ§ããã°ã©ã ã§ã
- ã¹ã¬ããã»ã¢ãã£ããã£ã®ããããã¯æ©æ§ïŒlock/mutex/semaphoreïŒã䜿çšããŠã³ãŒããããã¯ãããã¯ããŠããå Žåã«ã
- await ã䜿çšããŠä¿®æ£å€æŽããããå ŽåïŒawait æŒç®åãå«ãã³ãŒããããã¯ãããã¯ãããå ŽåïŒã
ã¹ã¬ããã»ã¢ãã£ããã£ã®ãªãããã¯æ©æ§ã䜿çšããã
è£è¶³ïŒ
lockã®äžã§ã¯awaitãæžããªãïŒ: æ£ç¢ºã«ã¯ã
C# ã®æ§æãšããŠlockãããã¯å ã«awaitã¯æžããªã
ïŒã³ã³ãã€ã« ãšã©ãŒã«ãªãïŒãlock (_sync) { await DoAsync(); // â ã³ã³ãã€ã« ãšã©ãŒ }çç±ã¯åæã®èšãéãã
MonitorïŒlockã®å®äœïŒã
ã¹ã¬ããã»ã¢ãã£ããã£ãæã€ïŒååŸããã¹ã¬ããããè§£æŸã§ããªãïŒããã
awaitã®ååŸã§ã¹ã¬ãããå€ããåŸã以äžãæç«ããªãã代æ¿ã¯
SemaphoreSlimïŒäžèšåç §ïŒãprivate readonly SemaphoreSlim _lock = new(1, 1); await _lock.WaitAsync(); try { await DoAsync(); } finally { _lock.Release(); }
finallyã§ã®Release()ã¯å¿ é ïŒäŸå€æã«æ°žä¹ ããã¯ã«ãªãïŒããªãã.NET 9 ã§
System.Threading.Lockåã远å ããã
lockæããã®åã«å¯Ÿå¿ãããã
ãããåæçšã§ãããawaitã¯æžããªãç¹ã¯å€ãããªãã
Win32 ã®åŸ æ©é¢æ°ã® WaitFor[Single|Multi]Object ã¯äŸå€çã«äœ¿çšå¯ã
ãããã®åŸ æ©é¢æ°ã¯ã
- ã¹ã¬ããã»ã¢ãã£ããã£ã§ã¯ãªãã
- ãç¶æ å€åãïŒãã³ã·ã°ãã«ç¶æ ããã·ã°ãã«ç¶æ ãžã®å€åïŒã
åŸ ã€é¢æ°ã§ãããããšèããã
- ã¹ã¬ããã»ã¢ãã£ããã£ã®ãªãããã¯æ©æ§
- .NET TIPSïŒéåæïŒawaitãå«ãã³ãŒããããã¯ããã«ã¯ïŒïŒSemaphoreSlimç·šïŒïŒ»C#ãVB - ïŒ IT
http://www.atmarkit.co.jp/ait/spv/1411/11/news117.html- SemaphoreSlim.WaitAsync 颿°ã async/await ããã
- Semaphore ã«ãã lock ãããã¿ã¹ã¯ãšããŠåå²ãããŠåŸ æ©/å®è¡ãããã
- ThreadPool ã¯ã©ã¹ (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.threadpool- ThreadPool.RegisterWaitForSingleObject ã¡ãœãã (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.threadpool.registerwaitforsingleobject
- ThreadPool.RegisterWaitForSingleObject ã¡ãœãã (System.Threading)
- EventWaitHandle ã¯ã©ã¹ (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.eventwaithandle- AutoResetEvent ã¯ã©ã¹ (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.autoresetevent - ManualResetEvent ã¯ã©ã¹ (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.manualresetevent
- AutoResetEvent ã¯ã©ã¹ (System.Threading)
- .NET TIPSïŒéåæïŒawaitãå«ãã³ãŒããããã¯ããã«ã¯ïŒïŒSemaphoreSlimç·šïŒïŒ»C#ãVB - ïŒ IT
è£è¶³ïŒãã ãããããã¯ããåŸ æ©ãã§ããç¹ã¯å€ãããªãïŒ: åæã®
ãWaitFor[Single|Multi]Object ã¯äŸå€çã«äœ¿çšå¯ãã¯
ã¹ã¬ããã»ã¢ãã£ããã£ã®èгç¹ã§ã¯æ£ãããã
åŸ ã£ãŠããéã¹ã¬ãããå æããç¹ã¯åãã§ãããéåææèã§ã¯ã次ã®åŸ ããªãåŸ æ©ã䜿ãã®ãå®ç³ã
åŸ ã¡ãããã® éåæç æä»å¶åŸ¡ SemaphoreSlim.WaitAsync()ã·ã°ãã« TaskCompletionSource<T>æé Task.Delay()ïŒThread.Sleepã¯äžå¯ïŒäžæéå§ TaskCompletionSource+Task.WhenAllçç£è ã»æ¶è²»è System.Threading.Channels
TaskCompletionSource<T>ã¯
ãå€éšã®ã€ãã³ããawaitå¯èœã«ãããããã®æ±çšææ®µã§ã
WaitHandleãåŸ ã€å Žåã
ThreadPool.RegisterWaitForSingleObjectãšçµã¿åãããŠ
Taskåããã®ãçŸåšã®æžãæ¹ã§ããã
äžèšã®ä»çµã¿ã§åããŠãããšãããšãé²æå ±åãã©ãå®è£
ããããïŒã§ãããã
以äžãèŠããšãProgress ã¯ã©ã¹ãIProgress<T> ã€ã³ã¿ãŒãã§ãŒã¹ã䜿çšãããããäºãè§£ãã
-
éåæã¡ãœãã - C# ã«ããããã°ã©ãã³ã°å ¥é | ++C++; // æªç¢ºèªé£è¡ C
http://ufcpp.net/study/csharp/sp5_async.html#cancel -
.NET TIPSïŒWPFïŒWindowsãã©ãŒã ïŒ
æéã®ãããåŠçãããã¯ã°ã©ãŠã³ãã§å®è¡ããã«ã¯ïŒïŒasyncïŒawaitç·šïŒïŒ»C#ïŒVB - ïŒ IT
http://www.atmarkit.co.jp/ait/articles/1512/02/news019.html
詳ããä»çµã¿ã¯äžæã ããGUI äžã§åäœããŠããããã
åæã³ã³ããã¹ãã® Control.Invokeã.BeginInvoke ã䜿çšããŠãããã®ãšæãããã
è£è¶³ïŒ
Progress<T>ã®ä»çµã¿ïŒ: åæã®æšæž¬ã¯æ£ããã
Progress<T>ã¯ã³ã³ã¹ãã©ã¯ã¿ã§å®è¡æã®åæã³ã³ããã¹ããææãã
Report()ãããããã®ã³ã³ããã¹ãã«ãã¹ãããã// UI ã¹ã¬ããã§çæããïŒïŒããã§ UI ã®åæã³ã³ããã¹ããæãŸããïŒ var progress = new Progress<int>(p => progressBar.Value = p); await DoWorkAsync(progress); // ã¯ãŒã«ãŒåŽã¯ Report ããã ãã§ããèŠç¹:
Progress<T>ã¯UI ã¹ã¬ããã§çæããããšã
ããã¯ã°ã©ãŠã³ãã§çæãããšåæã³ã³ããã¹ãã null ã«ãªãã
ã³ãŒã«ããã¯ã UI ã¹ã¬ããã§åãããäŸå€ã«ãªãããªããASP.NET Core ãªã©åæã³ã³ããã¹ããç¡ãç°å¢ã§ã¯
åžžã« ThreadPool äžã§åŒã°ããç¹ã«ã泚æã
-
.NET 4.0 ãã CancellationToken ãå©çšããã¿ã¹ã¯ã®ãã£ã³ã»ã«æ©æ§ãå°å ¥ãããã
- ã¿ã¹ã¯éå§åã«ããŒã¯ã³ããã£ã³ã»ã«ãããŠããã®ãã§ãã¯ãããããã¿ã¹ã¯ãéå§ããã³ã¹ããæžãã
- ThrowIfCancellationRequested ã¡ãœããã§ OperationCanceledExceptionïŒOCEïŒãã¹ããŒããå Žåã
- ã¿ã¹ã¯ã®æ¬äœã OCE ã«å«ãŸãããã£ã³ã»ã«ããŒã¯ã³ãç£èŠããŠããã
- åãã ã£ãããã¿ã¹ã¯ã®ã¹ããŒã¿ã¹ã¯ Canceled ã«ãªãïŒæ®éã¯ãFaultedïŒã
-
åè
-
ãC#ãTaskããã£ã³ã»ã«ãã - vaguely
http://mslgt.hatenablog.com/entry/2017/10/08/091841 -
ãC#ãã¿ã¹ã¯ã®ãã£ã³ã»ã«æ¹æ³ - Tumbling Dice
http://outofmem.hatenablog.com/entry/2014/04/02/014201 -
- c# - Cancellation token in Task constructor: why? - Stack Overflow
https://stackoverflow.com/questions/3712939/cancellation-token-in-task-constructor-why
- c# - Cancellation token in Task constructor: why? - Stack Overflow
-
Microsoft Learn
- ãããŒãžã ã¹ã¬ããã®ãã£ã³ã»ã«
https://learn.microsoft.com/ja-jp/dotnet/standard/threading/cancellation-in-managed-threads - CancellationToken Struct (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.cancellationtoken
- ãããŒãžã ã¹ã¬ããã®ãã£ã³ã»ã«
-
Qiita
- Cancellation Token ã«ã€ããŠèª¿ã¹ãŠã¿ã
https://qiita.com/TsuyoshiUshio@github/items/b2d23b37b410a2cfd330 - éåæã§è€æ°åŠçãå®è¡ãã察話åŒã§å¶åŸ¡ãã
https://qiita.com/haminiku/items/cc299c1ed94d7ba3f9ec
- Cancellation Token ã«ã€ããŠèª¿ã¹ãŠã¿ã
-
è£è¶³ïŒå®è£ ã®æéïŒ:
CancellationTokenã¯
å ¬éããéåæã¡ãœããã®æ«å°ŸåŒæ°ãšããŠåãåãã®ãæ £ç¿ã§ãããpublic async Task<T> GetAsync(string id, CancellationToken ct = default) { var res = await _http.GetAsync(url, ct); // äžæµãžå¿ ãæž¡ã ct.ThrowIfCancellationRequested(); // èªåã«ãŒãã§ã¯æç€ºçã«ç¢ºèª ... }èŠç¹:
- åãåã£ãããŒã¯ã³ã¯å¿ ãäžæµã«æµãïŒéäžã§æ¡ã朰ããªãïŒ
- ãã£ã³ã»ã«ã¯äŸå€ïŒ
OperationCanceledExceptionïŒã§äŒããã
ãããcatch (Exception)ã§ãŸãšããŠæ¡ããšãã£ã³ã»ã«ãå¹ããªããªã- ã¿ã€ã ã¢ãŠããåãä»çµã¿
ïŒnew CancellationTokenSource(TimeSpan.FromSeconds(5))ïŒ- ASP.NET Core ã§ã¯
HttpContext.RequestAbortedã
ã¯ã©ã€ã¢ã³ãåææã«ãã£ã³ã»ã«ãããããŒã¯ã³ãšããŠäœ¿ãã.NET 8 ã§ã¯
CancellationTokenSource.CancelAsync()ã远å ãããã
-
è€æ°ã®ã¿ã¹ã¯ãç¶ç¶ã«é£çµããæéã®ãããåæã³ã³ããã¹ããçµç±ããªãã
-
åè
- æ¹æ³: è€æ°ã®ã¿ã¹ã¯ãç¶ç¶ã«é£çµãã
https://learn.microsoft.com/ja-jp/dotnet/standard/parallel-programming/how-to-chain-multiple-tasks-with-continuations - Task.ContinueWith ã¡ãœãã (System.Threading.Tasks)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.tasks.task.continuewith
- æ¹æ³: è€æ°ã®ã¿ã¹ã¯ãç¶ç¶ã«é£çµãã
è£è¶³:
ContinueWithã¯async/await以åã®æžãæ¹ã§ããã
æ¢å®ã®ã¹ã±ãžã¥ãŒã©ãçŽæã«åããïŒTaskScheduler.Currentã䜿ãïŒçã®
èœãšã穎ããããããæ°èŠã³ãŒãã§ã¯awaitã䜿ãã
çŸåšãContinueWithãèŠãã®ã¯ã
ãæãã£ã±ãªãã¿ã¹ã¯ã®äŸå€ãæ¡ãããªã©éãããå Žé¢ã®ã¿ã
-
åæã³ã³ããã¹ãã䜿çšãããã»ããªãããå¶åŸ¡ã§ããã
-
åè
- Task.ConfigureAwait ã¡ãœãã (Boolean) (System.Threading.Tasks)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.tasks.task.configureawait
- Task.ConfigureAwait ã¡ãœãã (Boolean) (System.Threading.Tasks)
è£è¶³ïŒçŸåšã®æéïŒ:
ConfigureAwait(false)ã¯
ãawaitã®åŸã§ãå ã®åæã³ã³ããã¹ãã«æ»ããªããŠããã
ãšããæç€ºã§ããã
å Žæ æé ã©ã€ãã©ãª ConfigureAwait(false)ãä»ããïŒåŒã³åºãå ãéžã°ãªãïŒUI ã¢ã㪠ä»ããªãïŒUI æŽæ°ã®ããæ»ãå¿ èŠãããïŒ ASP.NET Core äžèŠïŒåæã³ã³ããã¹ããç¡ããã广ããªãïŒ ã³ã³ãœãŒã« äžèŠ .NET 8 ã§ã¯
ConfigureAwait(ConfigureAwaitOptions)ã远å ããã
SuppressThrowingïŒäŸå€ãæããã«åŸ ã€ïŒçãæå®ã§ããããã«ãªã£ãã
以äžã®åèè³æãããã¬ã€ãã©ã€ã³ãçºããŠã¿ãã
- åŒã³åºãåŽã§ã¿ã¹ã¯ã®çµäºãæ€åºããããšãã§ããªãã
- ã¿ã¹ã¯ã§çºçããäŸå€ãåŒã³åºãåŽã§è£è¶³ããããšãã§ããªãã
- äŸå€ïŒã€ãã³ããã³ãã©ã¯ OKïŒããããã€ãã³ããã³ãã©çšïŒã
â åé ã®çç±ã®ãããªæåã§ãåé¡ãªããç¡ãããã
- Task.Wait() ã¯ãéåæåŠçãåŸ æ©ããããããããããã¯ã®åå ã«ãªãæãã
- å®è¡ããéåæ Task ã®åã«ãTask.Wait ãå²ã蟌ããšãããããã¯ã«ãªã£ããããã
以äžããããããã¯ã®ãµã³ãã«ã
-
UI ã®å Žåã®ãµã³ãã«
åæã³ã³ããã¹ãã§ãã Windows ã¡ãã»ãŒãžã³ã°ãã¥ãŒã«ã
Task.Waitãéåæ Task ã®é ã§ãã¥ãŒã€ã³ã°ããããã
åè ãåŸè ã®å®äºãåŸ ã¡ç¶ããåŸè ãäœæè¿ãå®è¡ãããªãããïŒãšæãããïŒã- [C#] åæã¡ãœããããéåæã¡ãœãããåŒã³åºããš
ã¢ããªã±ãŒã·ã§ã³ãããªãŒãºãã - éåæã¡ãœããåŒã³åºãã«ãããããããã¯
https://www.ipentec.com/document/document.aspx?page=csharp-deadlock-call-async-method-from-sync-method
- [C#] åæã¡ãœããããéåæã¡ãœãããåŒã³åºããš
-
ASP.NET ã®å Žåã®ãµã³ãã«
åæã³ã³ããã¹ãã§ãã I/O å®äºããŒãã«ã
Task.Result(âTask.Wait)ãéåæ Task ã®é ã§ãã¥ãŒã€ã³ã°ããããã
åè ãåŸè ã®å®äºãåŸ ã¡ç¶ããåŸè ãäœæè¿ãå®è¡ãããªãããïŒãšæãããïŒã- ASP.NET ã§éåæ (Async) ãä¹ãããªã â Tsmatz
https://tsmatz.wordpress.com/2012/05/08/asp-net-mvc-async/- await ã§ Post ãããåæåŠçã¯ãGetHeader().ResultïŒéåæåŠçïŒ ã®åŠçãçµãããŸã§åŸ æ©ã
- åæã«ãGetHeader().ResultïŒéåæåŠçïŒ ã¯ããã® Post ãããåæåŠçãåŸ æ©ã
- ASP.NET ã§éåæ (Async) ãä¹ãããªã â Tsmatz
-
åè
- Task.Waitã®åé¡ç¹
http://outside6.wp.xdomain.jp/2016/08/06/post-343/ - async/await ïœéåæãªã©ã€ãã©ãªã¯æ¥œãããªãïœ - 飜ãã£ãœã人ã®ããã°@qwerty2501
http://qwerty2501.hatenablog.com/entry/2014/04/24/235849
- Task.Waitã®åé¡ç¹
è£è¶³ïŒãããããã¯ã®åçãäžæã§ïŒ: ãã®ãããããã¯ã¯
åæã³ã³ããã¹ããã1 ã€ããéããªããããšã«èµ·å ãããâ UI ã¹ã¬ããïŒDoAsync().Result ã§åŸ æ©ïŒUI ã¹ã¬ãããå æãããŸãŸïŒ â â¡ DoAsync å ã® await ãå®äº â ãç¶ããã UI ã¹ã¬ããã§å®è¡ããããšãã â ⢠ããã UI ã¹ã¬ãã㯠â ã§å¡ãã£ãŠãã â â£ â¡ ã¯æ°žä¹ ã«å®è¡ããããâ ãæ°žä¹ ã«åŸ ã¡ç¶ãã â ãããããã¯è§£æ±ºã¯ 2 ã€ãããªãã
.Result/.Wait()ã䜿ãããæåŸãŸã§awaitããïŒæšå¥šïŒ- ã©ã€ãã©ãªåŽã§
ConfigureAwait(false)ãä»ãã
â¡ ã UI ã¹ã¬ããã«æ»ãããšããªãããã«ããïŒå¯Ÿççæ³ïŒ**ãasync ã¯äžããäžãŸã§ïŒasync all the wayïŒã**ãšããååã¯ã
ãã®æ§é ããå°ããããéäžã§åæã«æ»ããŠã¯ãªããªãã
ãã£ããã以äžã®ã¬ã€ãã©ã€ã³ã«åŸãã
-
åºæ¬çã«åæã§å®è£ ããã
-
éåæã¯ãasync/await ã䜿çšããªãåŸæ¥ã®éåæã§å®è£ ããã
- ã³ãŒã«ã¹ã¿ãã¯ã®äžäœã§ async ã䜿ããšãåŒåºåŽã async ã®äœ¿çšãå¿ èŠã«ãªãã
- ãã®ãããäžçªå€åŽãŸã§ async ã䜿ãããã«ããå¿ èŠãããã
- ããããåäœãå€ããããšãã§ããªãã±ãŒã¹ãããã®ã§ã
Task.Wait ããã®ä»ã®ãããã¯ææ®µã䜿ã£ãŠåæãåããããªããªãã
-
async/await ã䜿çšããå Žåã
- Task ãè¿ãã ãã«ããŠãTask.Run ã¯äœ¿ããªãããã«ããã
- ã©ã€ãã©ãªå ã§ await ããå Žåã¯ãConfigureAwait(false) ã䜿ãã
詳ããã¯ãäžèšãåç §ã®ããšã
- ã¢ã³ããã¿ãŒã³
public static async Task FetchFileAsync(int fileNum)
{
await Task.Run(() =>
{
var contents = IO.DownloadFile();
Console.WriteLine("Fetched file #{0}: {1}", fileNum, contents);
});
}-
çç±ïŒ
-
ã©ã€ãã©ãªãã°ããŒãã«å ±æãªãœãŒã¹ã§ãã ThreadPool ã䜿çšããããšã«ãªãã
-
ã©ã€ãã©ãªã¯ãå®è¡ã³ã³ããã¹ããäžæãªã®ã§ãThreadPool å©çšã®æ±ºå®ã¯ã
ã©ã€ãã©ãªéçºè ã§ã¯ãªãã¢ããªã±ãŒã·ã§ã³éçºè ãããã¹ãã -
ã©ã€ãã©ãªãéåæã¡ãœãããæäŸããã®ã¯ãã€ãã£ãéåæã¡ãœããã䜿çšããå Žåã
- ãã€ãã£ãéåæã¡ãœããã¯ã¹ã¬ããããŒã«ã䜿ã£ãå¥ã¹ã¬ããã«ããéåæåŠçãç®çãšããŠããªãã
- I/O ãªã©ã®åŸ ã¡ã«å¯ŸããŠã¹ã¬ããã空ããŠåæå®å¹æ§ãé«ããããšãç®çã
-
-
ãµãŒãã§ã® Task.Run
- ãµãŒãã§ Task.Run ã䜿ããªãã
- çç±ïŒ
- Task.Run ã¯ã¹ã±ãŒã©ããªãã£ãæ±ãããããµãŒãã§ã¯äžé©å
- I/O ããŠã³ãã®å ŽåïŒCPU ããŠã³ãã§ãªãå ŽåïŒã ããéåæã¿ã¹ã¯ãå®çŸ©ããæå³ããããã
ãã®æ±ºå®ã¯ã©ã€ãã©ãªéçºè ã§ã¯ãªãã¢ããªã±ãŒã·ã§ã³éçºè ããããã®ã
-
ã¯ã©ã€ã¢ã³ãã§ã® Task.Run
- ã¯ã©ã€ã¢ã³ãã§ããTask.Run ã䜿ããªãã
- çç±ïŒ
- ã¯ã©ã€ã¢ã³ãåŽã§ã¯ Task.Run ã䜿ãçç±ãããããããã
- ãããåè¿°ã«ããããã«ãå®è¡ã³ã³ããã¹ããäžæãªã®ã§ãã©ã€ãã©ãªå ã§ Task.Run ã䜿ããªãã
-
äŸå€
-
äŸå€: ãã«ãã¹ã¬ãããš WinJS
WinJS ã¯æ°ããããã¯ã°ã©ãŠã³ãã¹ã¬ãããäœãããšãã§ããªãã®ã§ããããã«ã©ã€ãã©ãªåŽã§äœãå¿ èŠãããã -
äŸå€: Stream.ReadAsync
- ããçš®ã®ã¹ããªãŒã ã¯ããããµããŒãããªãã
- ãµããŒããããªãå Žåã¯ãåºåºã¯ã©ã¹ïŒStream ã¯ã©ã¹ïŒã§ Task.Run ãå®è¡ããã®ãæãå®å šãªæ¹æ³
-
ç§»è¡ã¡ã¢ïŒèª€èšïŒ: åæã®ãéåæ t ã¿ã¹ã¯ãã¯
éåæã¿ã¹ã¯ã®èª€èšããSteam ã¯ã©ã¹ã㯠Stream ã¯ã©ã¹ ã®èª€èšãš
倿ãä¿®æ£ããã
è£è¶³ïŒãåœã®éåæããšããã¢ã³ããã¿ãŒã³ïŒ: ãã®ç¯ãææããŠãã
Task.Runã§ã©ããããã ãã®éåæã¯ã
fake async / async over sync ãšåŒã°ãã代衚çãªã¢ã³ããã¿ãŒã³ã§ããããæ¬ç©ã®éåæïŒI/OïŒã HTTP èŠæ±ãåºã â ã¹ã¬ãããè¿ã â å¿çãæ¥ããç¶ããå®è¡ â åŸ ã£ãŠããéãã¹ã¬ãã㯠0 æ¬ ãTask.Run ã§å ãã ã ãã å¥ã®ã¹ã¬ããã 1 æ¬åããŠãããã§ãããã¯ããŠåŸ ã€ â æ¶è²»ããã¹ã¬ããã¯æžã£ãŠããªãããããåãæ¿ãã®ã¶ãå¢ãããµãŒãã§ã¯ç¹ã«æå®³ã§ã
ãéåæã«ããã®ã«ã¹ã«ãŒããããäžãããªãã
ããããã¹ã¬ãã ããŒã«ãæ¯æžãããã®åå ã«ãªããéã«ãCPU ããŠã³ãã®åŠçã UI ã¹ã¬ããããéããç®çã§
ã¢ããªã±ãŒã·ã§ã³åŽãTask.Runã䜿ãã®ã¯æ£ããçšéã§ããã
åæã®äž»åŒµã¯ãã©ã€ãã©ãªãåæã«æ±ºãããªããšããç¹ã«ããã
-
ããã¯ä»¥äžã®æ§ãªãŠãŒã¶ã®ä»®å®ã«åºã¥ãããã
-
åæããŒãžã§ã³ã®æ¹ãéåæããŒãžã§ã³ããé«éïŒãšèšãä»®å®ïŒã
éåæããŒãžã§ã³ããé«éãªåæããŒãžã§ã³ãæäŸã§ããªãå Žåã- äž¡æ¹ã®ããŒãžã§ã³ãæäŸããïŒïŒã©ãããæäŸããïŒçç±ãç¡ãã
- éåæããŒãžã§ã³ãåŒã³åºããšãã« Task.Wait ã䜿ã£ãŠåæããšãã»ããè¯ãã
-
åæããŒãžã§ã³ã¯ãUI ã¹ã¬ããã§å®è¡ããŠãå®å šïŒãšèšãä»®å®ïŒã
éåæã¡ãœãããã©ããããåæã¡ãœããã Task.Wait ã䜿ã£ãŠããå Žåããããããã¯ãçºçããå¯èœæ§ãããã
-
-
åŸã£ãŠãæšå¥šã¯ã
- ã¡ãœãããåæåŠçãè¡ããªããåæããŒãžã§ã³ã ããæäŸããã
- ã¡ãœãããéåæåŠçãè¡ããªãã
- éåæããŒãžã§ã³ã ããæäŸããã
- é«éã«åäœãããããããã¯ãèµ·ãããªãåæã¡ãœããã®ã¿è¿œå ã§å®çŸ©å¯èœã
-
åºæ¬çã«ã¯ã©ã€ãã©ãªå ã§ await ããå Žå㯠ConfigureAwait(false) ããã
- æ§èœçã«æ©ããªãã
- UI ã®å Žåã®åæã³ã³ããã¹ãã§ãã Windows ã¡ãã»ãŒãžã³ã°ãã¥ãŒãªã©ã
åæã³ã³ããã¹ãã«ãã£ãŠã¯ããããããã¯ãããå¯èœæ§ãé«ããªãã
-
ConfigureAwait(false) ãããšå ã®ã¹ã¬ãã(䞻㫠UI ã¹ã¬ãã)ã«ã¯æ»ããªãã
å¿ èŠã«å¿ããŠãåæã³ã³ããã¹ãã«ããåäœã¹ã¬ããã®åãæ¿ããè¡ãã
// UIã¹ã¬ããã®åæã³ã³ããã¹ãããã£ãã·ã¥ãã
SynchronizationContext syncContext = SynchronizationContext.Current;
//.ConfigureAwait(false)ã§UIã¹ã¬ããã«æ»ããªã
await HeavyWorkAsync().ConfigureAwait(false);
// UIã¹ã¬ããã®åæã³ã³ããã¹ãã«ãã£ã¹ãããããã
syncContext.Post(state =>
{
// äœããã®åŠçã
}, null);-
å®è¡ã³ã³ããã¹ããã³ããŒããã
- ãã°ã€ã³ã»ãŠãŒã¶ãã«ã«ãã£æ
å ±ãªã©åœè£
ãããå Žåã
CallContext.SetLocalData ã䜿çšããŠãå®è¡ã³ã³ããã¹ããã³ããŒããã - ãã®åŠçã¯éåæåŒã³åºãã«å°éã®æ§èœã³ã¹ãã远å ããã
- ãã°ã€ã³ã»ãŠãŒã¶ãã«ã«ãã£æ
å ±ãªã©åœè£
ãããå Žåã
-
ã«ãŒãå ã§åŒã³åºããªãã
- async ã䜿ã£ãã¡ãœãã㯠Task ã®çæã Task ã®å®è¡ç®¡çã®ããã®ã³ã¹ãããããã
- åŸã£ãŠãã©ã€ãã©ãªã®ãŠãŒã¶ã«ã¯ã«ãŒãå ã§åŒã³åºããªãããã«æ³šæåèµ·ããã
-
åè
- Async/Await- ããã©ãŒãã³ã¹äžã®ãªãŒããŒããããšä»ã®èœãšã穎
http://www.infoq.com/jp/news/2013/07/async-await-pitfalls- Async/Await - Best Practices in Asynchronous Programming
http://msdn.microsoft.com/en-us/magazine/jj991977.aspx
- Async/Await - Best Practices in Asynchronous Programming
- Async/Await- ããã©ãŒãã³ã¹äžã®ãªãŒããŒããããšä»ã®èœãšã穎
è£è¶³ïŒ
CallContext㯠.NET Core ã§ã¯äœ¿ããªãïŒææ°åïŒ:CallContext
ïŒSystem.Runtime.Remoting.MessagingïŒã¯ .NET Framework å°çšã§ã
.NET Core 以éã§ã¯å©çšã§ããªããç§»è¡å ã¯
AsyncLocal<T>ã§ãããprivate static readonly AsyncLocal<string> _tenant = new(); _tenant.Value = "contoso"; // await ããŸããã§åŒãç¶ããã
ThreadLocal<T>AsyncLocal<T>åäœ ã¹ã¬ãã éåæã®æµãïŒå®è¡ã³ã³ããã¹ãïŒ awaitåŸå€±ããã åŒãç¶ããã ASP.NET Core ã®
IHttpContextAccessorããã®ä»çµã¿ã§å®è£ ãããŠããã
ãªããåæã®ææéãã³ããŒã«ã¯ã³ã¹ããããããã
䜿ããããªãïŒDI ã§åŒãåãããªããã¡ãã䜿ãïŒæ¹ãããã
éåæã¡ãœããã®åŒã³åºãã¯æ¬¡ã® 3 ã€ã®ã¡ã¢ãªç¢ºä¿åŠçãçãã
- â¯:ããŒã«ã«ã®å€æ°ãä¿åããããã®ã¹ããŒããã·ã³
- â¯:ç¶ç¶ã®ããã®ããªã²ãŒã
- çµæãè¿ãããã®ã¿ã¹ã¯
â¯ãä»äžããããã¹ããŒããã·ã³ãšããªã²ãŒã㯠await ããŒã¯ãŒãã
ã©ã³ã¿ã€ã ã«çŸãããšãã«äœæããããããåæåŠçãšæ¯ã¹ããšã³ã¹ãã«ãªãã
è£è¶³ïŒçŸåšã¯å€§å¹ ã«æ¹åãããŠããïŒææ°åïŒ: ãã®ç¯ã®èšè¿°ã¯
.NET Framework æä»£ã®å®è£ ãåæãšããŠããã
ãã®åŸãæ¬¡ã®æ¹åãå ¥ã£ãã
æ¹å å 容 ã¹ããŒã ãã·ã³ã®æ§é äœå åæå®äºããå ŽåãããŒã確ä¿ãèµ·ããªã ValueTask<T>åæå®äºæã« Taskã®ç¢ºä¿ãåé¿IValueTaskSourceTask ãªããžã§ã¯ãã®åå©çšïŒSocket çã§å©çšïŒ Async ValueTask Pooling ã¹ããŒã ãã·ã³ã®ããŒã«ïŒ.NET 5+ãæ¢å®ãªãïŒ çŸåšã¯ãåæçã«å®äºãããã¹ã§ã¯ã¢ãã±ãŒã·ã§ã³ãã»ãŒçºçããªã
ãšãããŸã§æé©åãããŠããããã ãåæã®çµè«ãã«ãŒãå ã§å€§éã«åŒã°ãªããã¯äŸç¶æå¹ã§ã
ç¹ã«1 ä»¶ãã€awaitãã N+1 ãã¿ãŒã³ã¯é¿ããã¹ãã§ããã// æªãïŒ1 ä»¶ãã€é çªã«åŸ ã€ïŒN åã®ã©ãŠã³ãããªããïŒ foreach (var id in ids) results.Add(await GetAsync(id)); // è¯ãïŒãŸãšããŠäžŠè¡ã«æããïŒäžŠå床ã®å¶åŸ¡ã¯å¿ èŠïŒ var results = await Task.WhenAll(ids.Select(GetAsync)); // ããè¯ãïŒäžŠå床ãå¶éããïŒ.NET 6+ïŒ await Parallel.ForEachAsync(ids, new ParallelOptions { MaxDegreeOfParallelism = 8 }, async (id, ct) => { ... });
-
C#ã®éåæã®èœãšã穎
https://www.infoq.com/jp/news/2013/04/async-csharp-fsharp -
Async in C# and F#: Asynchronous gotchas in C# (Japanese translation)
https://gist.github.com/pocketberserker/5565303 -
neue cc
- asyncã®èœãšã穎Part2, SynchronizationContextã®åããåŽ
http://neue.cc/2013/07/02_412.html - asyncã®èœãšã穎Part3, async voidãé¿ããã¹ã100åã®çç±
http://neue.cc/2013/10/10_429.html
- asyncã®èœãšã穎Part2, SynchronizationContextã®åããåŽ
-
TAP (Task-based Asynchronous Pattern) éåæã¡ãœããã®ã¬ã€ãã©ã€ã³ - Qiita
http://qiita.com/chocolamint/items/ed4999cccf011653cb78 -
.NETã§éåæã©ã€ãã©ãªãæ£ããå®è£ ãã
https://www.infoq.com/jp/articles/Async-API-Design- Creating Async Libraries That Are Modular, Reusable and Fast,
in Microsoft Visual C# and Visual Basic | TechEd Europe 2013 | Channel 9
https://channel9.msdn.com/Events/TechEd/Europe/2013/DEV-B318
- Creating Async Libraries That Are Modular, Reusable and Fast,
-
Tasks are (still) not threads and async is not parallel
http://blogs.msdn.com/b/benwilli/archive/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel.aspx
è£è¶³ïŒèŠç¹ã®èŠçŽïŒ: é·ãããŒãžãªã®ã§ãå®åäžã®æéã 7 ç¹ã«çºããã
asyncã¯äžããäžãŸã§ãéäžã§.Result/.Wait()ã«æ»ããªããasync voidã¯ã€ãã³ã ãã³ãã©ãŒã ãã- ã©ã€ãã©ãªã§ã¯
ConfigureAwait(false)ïŒASP.NET Core ã§ã¯äžèŠïŒã- I/O ã¯æ¬ç©ã®éåæ API ã䜿ãã
Task.Runã§å ãŸãªããCancellationTokenãåãåããäžæµãžæµãã- 䞊åãšéåæãåºå¥ãããCPU ããŠã³ãã¯
Parallelç³»ãlockã®äžã§awaitããªããSemaphoreSlimã䜿ãã
-
Insider.NET > æ¥åã¢ããªInsider
- é£èŒïŒC# 5.0ïŒVB 11.0æ°æ©èœãasyncïŒawaitéåæã¡ãœãããå
¥é -ïŒ IT
http://www.atmarkit.co.jp/ait/subtop/features/dotnet/app/masterasync_index.html
- é£èŒïŒC# 5.0ïŒVB 11.0æ°æ©èœãasyncïŒawaitéåæã¡ãœãããå
¥é -ïŒ IT
-
Taskãæ¥µããïŒasync/awaitå®å šæ»ç¥ - Qiita
http://qiita.com/acple@github/items/8f63aacb13de9954c5da -
ASP.NET ã§éåæ (Async) ãä¹ãããªã | Tsmatz
https://tsmatz.wordpress.com/2012/05/08/asp-net-mvc-async/
- éåæããã°ã©ãã³ã° (C#)
https://learn.microsoft.com/ja-jp/dotnet/csharp/asynchronous-programming/ - ã¿ã¹ã¯ ããŒã¹ã®éåæãã¿ãŒã³ (TAP)
https://learn.microsoft.com/ja-jp/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap - ConfigureAwait FAQ
https://devblogs.microsoft.com/dotnet/configureawait-faq/
- TPLå
¥é
http://blog.xin9le.net/entry/tpl-intro - éåæã¡ãœããå
¥é
http://blog.xin9le.net/entry/async-method-intro
- éåæåŠç(ã€ã³ããã¯ã¹) - MakCraft
http://www.makcraft.com/devref/26-asynchronous-processing-index.html
- (ãã®1)
http://www.makcraft.com/blog/meditation/2013/03/22/asynchronous-processing-part-1/ - (ãã®2)
http://www.makcraft.com/blog/meditation/2013/03/23/asynchronous-processing-part-2/ - (ãã®3)
http://www.makcraft.com/blog/meditation/2013/03/23/asynchronous-processing-part-3/ - (ãã®4)
http://www.makcraft.com/blog/meditation/2013/03/24/asynchronous-processing-part-4/ - (ãã®5)
http://www.makcraft.com/blog/meditation/2013/04/02/asynchronous-processing-part-5/
- ãããã¥ãŒãµãŒ/ã³ã³ã·ã¥ãŒã㌠ãã¿ãŒã³
http://www.makcraft.com/blog/meditation/2013/03/24/producer-consumer-pattern/ - ãå©çšãããµãŒããŒåŽæ¥ç¶åŠç
http://www.makcraft.com/blog/meditation/2013/04/04/server-side-connection-processing-using-the-producer-consumer-pattern/ - ãå©çšãã IPv4 åã³ IPv6 æ¥ç¶åŸ
ã¡
http://www.makcraft.com/blog/meditation/2013/04/06/listen-on-ipv6-and-ipv4-based-producer-consumer-pattern/
Tags: ç§»è¡, ããã°ã©ãã³ã°, .NETéçº