ã»ãŒãã¹ãŠã®å®éã®ãããžã§ã¯ãã¯ã
çç£è
ãšæ¶è²»è
ã®ãã¥ãŒã®å®è£
ã®äœããã®åœ¢ã䜿çšããŠãããšæã
ãŸã ã åé¡ã®èåŸã«ããèãæ¹ã¯éåžžã«ç°¡åã§ãã ã¢ããªã±ãŒã·ã§ã³ã¯ãåŠçããããŒã¿ã®çæãåãé¢ãå¿
èŠããããŸãã ããšãã°ãCLRã®ã¹ã¬ããããŒã«ã
èããŠã¿ãŸããã
ãThreadPool.QueueUserWorkItemãåŒã³åºãããšã§åŠçããèŠçŽ ã远å ããŸããã¹ã¬ããããŒã«èªäœã¯ãæé©ãªã¯ãŒã¯ãããŒã®æ°ãçè§£ããå¿
èŠãªäžŠå床ã§èŠçŽ ãåŠçããã¡ãœãããåŒã³åºããŸãã
ãã ããæšæºã®ã¹ã¬ããããŒã«ã䜿çšããããšã¯ãåžžã«å¯èœãŸãã¯åççã§ã¯ãããŸããã ã¹ã¬ããã®æå°æ°ãšæå€§æ°ãæå®ããå¯èœæ§ã«ããããããããã®æ§æã¯ã°ããŒãã«ã§ãããå¿
èŠãªéšåã§ã¯ãªãã¢ããªã±ãŒã·ã§ã³å
šäœã«åœ±é¿ããŸãã æ¶è²»è
ãµãã©ã€ã€ãŒã®åé¡ã解決ããæ¹æ³ã¯ä»ã«ããããããããŸãã ã¢ããªã±ãŒã·ã§ã³ããžãã¯ããã«ãã¹ã¬ããããã¥ãŒãããã³åæã®åŽé¢ãšæ··åšããŠããå Žåããæ£é¢ãã®ãœãªã¥ãŒã·ã§ã³ã«ãªãå¯èœæ§ããããŸãã ããã¯ãã¯ãŒã¯ãããŒãŸãã¯ã¿ã¹ã¯ã®æ°ãæåã§å¶åŸ¡ãã
BlockingCollectionã®ã©ãããŒã«ããããšãã§ããŸãã ãŸãã¯ãTPL DataFlowã®
ActionBlock <T>ãªã©ã®å®å
šãªãœãªã¥ãŒã·ã§ã³ã«åºã¥ãããœãªã¥ãŒã·ã§ã³ã«ããããšãã§ããŸãã
仿¥ã¯ã
ActionBlockã¯ã©ã¹ã®å
éšæ§é ã
調㹠ããã®äœæè
ãè¡ã£ãèšèšäžã®æ±ºå®ã«ã€ããŠè°è«ããäœ¿çšæã«åé¡ãåé¿ããããã«ããããã¹ãŠãç¥ãå¿
èŠãããçç±ãèŠã€ããŸãã æºåã¯ããïŒ ããã§ã¯è¡ããïŒ
ç§ã®çŸåšã®ãããžã§ã¯ãã§ã¯ããµãã©ã€ã€ãŒãšæ¶è²»è
ã®åé¡ã解決ããå¿
èŠãããããã€ãã®ã±ãŒã¹ããããŸãã ãã®1ã€ã¯æ¬¡ã®ããã«ãªããŸããTypeScriptã«éåžžã«ãã䌌ãèšèªçšã®ã«ã¹ã¿ã ããŒãµãŒãšã€ã³ã¿ãŒããªã¿ãŒããããŸãã è©³çŽ°ã«æ·±ãå
¥ã蟌ãããšãªããäžé£ã®ãã¡ã€ã«ãè§£æãããã¹ãŠã®äŸåé¢ä¿ã®ãããããæšç§»çã¯ããŒãžã£ãŒããååŸããå¿
èŠããããšèšããŸãã æ¬¡ã«ãå®è¡ã«é©ãããã¬ãŒã³ããŒã·ã§ã³ã«å€æããŠå®è¡ããå¿
èŠããããŸãã
è§£æããžãã¯ã¯æ¬¡ã®ããã«ãªããŸãã
- Parsimãã¡ã€ã«ã
- ãã®å
容ãåæãããã®äŸåé¢ä¿ãæ¢ããŸãïŒãã¹ãŠã®ãimport * fromãããrequireããããã³åæ§ã®æ§æãåæããŸãïŒã
- äŸåé¢ä¿ãèšç®ããŸãïŒã€ãŸããçŸåšã®ãã¡ã€ã«ãéåžžã®æäœã«å¿
èŠãªãã¡ã€ã«ã®ã»ãããèŠã€ããŸãïŒã
- åä¿¡ããäŸåé¢ä¿ãã¡ã€ã«ãè§£æçšã®ãªã¹ãã«è¿œå ããŸãã
ããªãç°¡åã§ããã ããã§ãã TPL Dataflowããã³
ActionBlock <T>ã¯ã©ã¹ã«åºã¥ãããããã«åçŽåãããå®è£
ã¯æ¬¡ã®ããã«ãªããŸãã
private static Task<ParsedFile> ParseFileAsync(string path) { Console.WriteLine($"Parsing '{path}'. {{0}}", $"Thread Id - {Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(10); return Task.FromResult( new ParsedFile() { FileName = path, Dependencies = GetFileDependencies(path), }); } static void Main(string[] args) { long numberOfProcessedFiles = 0; ActionBlock<string> actionBlock = null; Func<string, Task> processFile = async path => { Interlocked.Increment(ref numberOfProcessedFiles); ParsedFile parsedFile = await ParseFileAsync(path); foreach (var dependency in parsedFile.Dependencies) { Console.WriteLine($"Sending '{dependency}' to the queue... {{0}}", $"Thread Id - {Thread.CurrentThread.ManagedThreadId}"); await actionBlock.SendAsync(dependency); } if (actionBlock.InputCount == 0) {
ããã§äœãèµ·ãããèŠãŠã¿ãŸãããã ç°¡åã«ããããã«ããã¹ãŠã®ã³ã¢ããžãã¯ã¯
Mainã¡ãœããã«ãããŸãã 倿°
numberOfProcessedFiles㯠ãããžãã¯ãæ£ããããšã確èªããããã«äœ¿çšãããåŠçããããã¡ã€ã«ã®ç·æ°ãå«ãŸããŸãã äž»ãªäœæ¥ã¯
processFileããªã²ãŒãã§è¡ãããããªã²ãŒãã¯
ActionBlockã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããŸãã ãã®ããªã²ãŒãã¯ããã³ã³ã·ã¥ãŒãããšããããã€ããŒãã®äž¡æ¹ã®åœ¹å²ãæãããŸã
ãpathåŒæ°ãä»ããŠãã¡ã€ã«ãã¹ã
ååŸãããã¡ã€ã«ãè§£æããŠãäŸåé¢ä¿ãèŠã€ãã
actionBlock.SendAsyncã¡ãœãããåŒã³åºããŠãã¥ãŒã«æ°ãããã¡ã€ã«ãéä¿¡ããŸãã æ¬¡ã«ãåŠçãã¥ãŒå
ã®èŠçŽ æ°ã®ãã§ãã¯ããããæ°ããèŠçŽ ããªãå Žåã¯ã
actionBlock.CompleteïŒïŒ ïŒ*ïŒãåŒã³åºãããšã§æäœå
šäœãå®äºããŸãã æ¬¡ã«ã
Mainã¡ãœããã¯
ActionBlockã€ã³ã¹ã¿ã³ã¹ãäœæããæåã®ãã¡ã€ã«ã®åŠçãéå§ããŠãããã»ã¹å
šäœã®çµäºãåŸ
ã¡ãŸãã
ParseFileAsyncã¡ãœããã¯ããã¡ã€ã«è§£æããã»ã¹ããšãã¥ã¬ãŒãããæ¬¡ã®ããªããã£ãããžãã¯ã䜿çšããŠäŸåé¢ä¿ãèšç®ããŸãããã¡ã€ã«ãfoo.tsãã¯ãfo.tsãã«äŸåãããfo.tsãã¯ãf.tsãã«äŸåããŸãã ã€ãŸã åãã¡ã€ã«ã¯ãçãååã®ãã¡ã€ã«ã«äŸåããŠããŸãã ããã¯éçŸå®çãªããžãã¯ã§ããããã¡ã€ã«ã®æšç§»çãªéå
ãèšç®ããåºæ¬çãªèãæ¹ã瀺ãããšãã§ããŸãã
ActionBlockã¯ã©ã¹ã¯ãäžŠè¡æ§ã管çããŸãã
確ãã« ãããã©ã«ãã®äžŠå床ã¯1ã§ããããšãèæ
®ããå¿
èŠããããããã倿Žããã«ã¯ã
ActionBlockã³ã³ã¹ãã©ã¯ã¿ãŒã§
ExecutionDataflowBlockOptionsã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãæž¡ãå¿
èŠããããŸãã
MaxDegreeOfParallelismããããã£ã1ãã倧ããå Žåã
ActionBlockã¯ç°ãªãã¹ã¬ããïŒå®éã«ã¯ç°ãªãã¿ã¹ã¯ïŒããã³ãŒã«ããã¯ããªã²ãŒããåŒã³åºããŠããã¥ãŒèŠçŽ ã䞊ååŠçããŸãã
æçš¿ãš SendAsyncïŒäœããã€äœ¿çšããã
äŸçµŠè
ãšæ¶è²»è
ã®åé¡ãå°ãªããšãäžåºŠç¬ç«ããŠè§£æ±ºããããšãã人ã¯èª°ã§ãåé¡ã«çŽé¢ããŸãããå
¥åããŒã¿ã¹ããªãŒã ãåŠçäžã®æ¶è²»è
ã®èœåãè¶
ããå Žåã¯ã©ãããã°ããã§ãããã å
¥åã¹ããªãŒã ããçµããæ¹æ³ã¯ïŒ ãã¹ãŠã®å
¥åèŠçŽ ãã¡ã¢ãªã«ä¿åããã ãã§ããïŒ äŸå€ãæããŸããïŒ ã¢ã€ãã ã®è¿œå ã¡ãœããã§
falseãè¿ã
ãŸããïŒ åŸªç°ãããã¡ã䜿çšããŠå€ãèŠçŽ ãç Žæ£ããŸããïŒ ãŸãã¯ããã¥ãŒã«å Žæã衚瀺ããããŸã§ãã®ã¡ãœããã®å®è¡ããããã¯ããŸããïŒ
ãã®åé¡ã解決ããããã«ã
ActionBlockã®äœæè
ã¯ã次ã®äžè¬çã«åãå
¥ããããŠããã¢ãããŒãã䜿çšããããšã«ããŸããã
- ã¯ã©ã€ã¢ã³ãã¯ã ActionBlockãªããžã§ã¯ããäœæãããšãã«ãã¥ãŒã®ãµã€ãºãæå®ã§ããŸãã
- ãã¥ãŒããã£ã±ãã®å Žåã Postã¡ãœããã¯falseãè¿ãã SendAsyncæ¡åŒµã¡ãœããã¯ããã¥ãŒã«ç©ºãé åããããšãã«å®äºããã¿ã¹ã¯ãè¿ããŸãã
åã®äŸã§ã¯ããã¥ãŒã®ãµã€ãºãèšå®ããŸããã§ããã ãŸããããã¯ãæ°ããèŠçŽ ãåŠçããããããéã远å ããããšãã¢ããªã±ãŒã·ã§ã³ãé
ããæ©ãã
OutOfMemoryExceptionã§ã¯ã©ãã·ã¥ããããšãæå³ããŸãã ãããããã®ç¶æ³ãä¿®æ£ããŠã¿ãŸãããã ãããŠããã¥ãŒãéåžžã«å°ããªãµã€ãºãããšãã°1èŠçŽ ã«èšå®ããŸãã
actionBlock = new ActionBlock<string>(processFile, new ExecutionDataflowBlockOptions() {BoundedCapacity = 1});
ããŠããã®ã³ãŒããå®è¡ãããšã...ãããããã¯ãçºçããŸãïŒ
ãããããã¯
ãã¶ã€ã³ã®èгç¹ããæ¶è²»è
ãšäŸçµŠè
ã®åé¡ãèããŠã¿ãŸãããã èŠçŽ ãåŠçããããã®ã³ãŒã«ããã¯ã¡ãœãããåãå
¥ããç¬èªã®ãã¥ãŒãäœæããŸãã èŠçŽ æ°ã®å¶éããµããŒããããã©ãããæ±ºå®ããå¿
èŠããããŸãã ãå¶éãããããã¥ãŒãå¿
èŠãªå Žåããããã
ActionBlockã¯ã©ã¹ã®èšèšã«éåžžã«ãã䌌ãèšèšã«ãªããŸãããã¥ãŒããã£ã±ãã®å Žåã«
falseãè¿ãèŠçŽ ã远å ããåæã¡ãœãããšãã¿ã¹ã¯ãè¿ãéåæã¡ãœããã远å ããŸãã ãã¥ãŒããã£ã±ãã®å Žåãã¯ã©ã¹ã®ã¯ã©ã€ã¢ã³ãã¯äœããã¹ãããæ±ºå®ããæ©äŒããããŸããèŠçŽ ã远å ããåæããŒãžã§ã³ãåŒã³åºãããšã§ç¬èªã«ããªãŒããŒãããŒããåŠçããããéåæããŒãžã§ã³ã䜿çšããŠãã¥ãŒå
ã®ç©ºãã¹ããŒã¹ã®åºçŸããåŸ
æ©ãããŸãã
次ã«ãã³ãŒã«ããã¯ã¡ãœããããã€åŒã³åºãããæ±ºå®ããå¿
èŠããããŸãã ãã®çµæã次ã®ããžãã¯ã«å°éã§ããŸãããã¥ãŒã空ã§ãªãå Žåãæåã®èŠçŽ ãååŸãããã³ãŒã«ããã¯ã¡ãœãããåŒã³åºãããåŠçãå®äºãããšäºæ³ããããã®åŸèŠçŽ ããã¥ãŒããåé€ãããŸãã ïŒå®éã®å®è£
ã¯ãããããçš®é¡ã®äººçš®ãèæ
®ã«å
¥ããå¿
èŠããããããèŠãããããã¯ããã«è€éã«ãªããŸãïŒã ãã¥ãŒã¯ãã³ãŒã«ããã¯ã¡ãœãããåŒã³åºãåã«ã¢ã€ãã ãåé€ããããšã決å®ã§ããŸãããããã«ãããããã«ãããã¯ãããããã¯ãåãåãå¯èœæ§ã«åœ±é¿ããŸããã
ã·ã³ãã«ã§ãšã¬ã¬ã³ããªãã¶ã€ã³ãæãã€ããŸããããç°¡åã«åé¡ã«ã€ãªããå¯èœæ§ããããŸãã ãã¥ãŒããã£ã±ãã§ãèŠçŽ ã®1ã€ãåŠçããããã«ã³ãŒã«ããã¯ãåŒã³åºãããŠãããšããŸãã ãããã管çãã¥ãŒããã°ãããè¿ãã代ããã«ããã³ãã©ãŒã
await SendAsyncãåŒã³åºã
ãŠå¥ã®èŠçŽ ã远å ããããšãããš
ã©ããªããŸããã
ã³ãŒã«ããã¯ã¡ãœããããŸã å®äºããŠããªãããããã¥ãŒããã£ã±ãã§æ°ããã¢ã€ãã ãåãå
¥ããããšãã§ããŸããã ãããããã®ã¡ãœãããã
SendAsyncã®åŸ
æ©
ãå®äºããã®ã
åŸ
ã£ãŠ ã¹ã¿ãã¯ã ãå Žæããã¥ãŒã€ã³ã°ããããŸã§ç§»åã§ããŸããã§ããã å€å
žçãªãããããã¯ïŒ
ã³ãŒã«ããã¯ã¡ãœããã*å®äºããåŸã
ActionBlockããã¥ãŒããã¢ã€ãã ãåé€ããããããããããã¯ãçºçããŸãã ããããå¥ã®ã·ããªãªãèŠãŠã¿ãŸãããïŒ
ActionBlockãã³ãŒã«ããã¯ã¡ãœãããåŒã³åºãåã«*èŠçŽ ã
åé€ãããšã©ããªããŸããïŒ å®éãäœãå€ãããŸããã ãããããã¯ã¯åŒãç¶ãå¯èœã§ãã
ãã¥ãŒãµã€ãºã1ã§ã䞊å床ã2ã§ãããšæ³åããŠãã ããã
- ã¹ã¬ããT1ã¯ãã¢ã€ãã ããã¥ãŒã«è¿œå ããŸãã ActionBlock㯠ããã¥ãŒããèŠçŽ ãåé€ãïŒãã¥ãŒå
ã®èŠçŽ ã®æ°ã0ã«æžãããŸãïŒãã³ãŒã«ããã¯ã¡ãœãããåŒã³åºããŸãã
- ã¹ã¬ããT2ã¯ãã¢ã€ãã ããã¥ãŒã«è¿œå ããŸãã ActionBlock㯠ããã¥ãŒããèŠçŽ ãåé€ãïŒãã¥ãŒå
ã®èŠçŽ ã®æ°ã0ã«æžãããŸãïŒãã³ãŒã«ããã¯ã¡ãœãããåŒã³åºããŸãã
- ã¹ã¬ããT1ã¯ãã¢ã€ãã ããã¥ãŒã«è¿œå ããŸãã 䞊ååŠçã®ã¬ãã«ã¯2ã§ããããã§ã«2ã€ã®ãã³ãã©ãŒããããããActionBlockã¯æ°ããèŠçŽ ã®ãã³ãã©ãŒãåŒã³åºãããšãã§ããŸããã ãã¥ãŒããã£ã±ãã§ãã
- åŠçäžã®æåã®ãã³ãã©ãŒã¯ããã¥ãŒã«æ°ããèŠçŽ ã远å ããããšããŸããããã¥ãŒããã£ã±ãã§ãããããã await SendAsync ãã®åŒã³åºãã«åºå·ããŸãã
- åŠçäžã®2çªç®ã®ãã³ãã©ãŒã¯ãæ°ããèŠçŽ ããã¥ãŒã«è¿œå ããããšããŸããããã¥ãŒããã£ã±ãã§ããããã ' await SendAsync 'ã®åŒã³åºãã«åºå·ããŸãã

åŠçåã«ãã¥ãŒããã¢ã€ãã ãåé€ããŠã广ããªãããšãããããŸãã ããã«ããããããã¯ã®ç¢ºçã倧å¹
ã«äœäžãããããããã¯åé¡ãæªåãããã ãã§ãïŒäžŠå床ãNã«çããå Žåããã¹ãŠã®Nã³ãŒã«ããã¯ã¡ãœãããæ°ããèŠçŽ ãåæã«ãã¥ãŒã«è¿œå ããããšããå¿
èŠããããŸãïŒã
å¥ã®æ¬ ç¹ã¯ããã»ã©æçœã§ã¯ãããŸããã
ActionBlockã¯ãŸã æ±çšãœãªã¥ãŒã·ã§ã³ã§ã¯ãããŸããã ãã®ã¯ã©ã¹ã¯
ITargetSourceã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããè€éãªããŒã¿ãããŒã¹ã¯ãªããã®èŠçŽ ãåŠçããããã«äœ¿çšã§ããŸãã ããšãã°ãèŠçŽ ã®äžŠååŠçã®ããã®ããã€ãã®ãã¿ãŒã²ããããããã¯ãæã€
BufferBlockããããŸãã çŸåšã®å®è£
ã§ã¯ããã©ã³ã·ã³ã°ãã³ãã©ãŒã¯ç°¡åãªæ¹æ³ã§å®è£
ãããŠããŸãã ã¬ã·ãŒããŒïŒãã®å Žåã¯
ActionBlock ïŒããã£ã±ãã«ãªããšãå
¥åçšã®æ°ããèŠçŽ ã®åãå
¥ãã忢ããŸãã ããã«ããããã§ãŒã³å
ã®ä»ã®ãããã¯ã代ããã«èŠçŽ ãåŠçã§ããŸãã
èŠçŽ ãåŠçãããåŸã«ã®ã¿åé€ãããå ŽåãActionBlockã¯è²ªæ¬²ã«ãªããçŸåšåŠçã§ãããããå€ãã®èŠçŽ ãåãå
¥ããŸãã ãã®å Žåãåãããã¯ã®å¶é容éã¯ãBoundedCapaciyã+ãMaxDegreeOfParallelismãã«çãããªããŸãã
ãããããã¯ã®åé¡ã解決ããæ¹æ³ã¯ïŒ
ç§ã¯äœãæããŠããªãã åæã«ãã¥ãŒå
ã®èŠçŽ ã®æ°ãå¶éããå¿
èŠããããã³ãŒã«ããã¯ã¡ãœãããæ°ããèŠçŽ ã远å ã§ãã
å Žå ã
ActionBlockãæŸæ£
ããå¿
èŠããã
ãŸã ã å¥ã®æ¹æ³ãšããŠã
BlockingCollectionãšã¯ãŒã¯ãããŒã®æ°ã®ãæåãå¶åŸ¡ã«åºã¥ããœãªã¥ãŒã·ã§ã³ããããŸããããšãã°ãã¿ã¹ã¯ããŒã«ãŸãã¯Parallel.Invokeã䜿çšããŸãã
䞊å床
TPLã®ããªããã£ããšã¯ç°ãªããTPL Dataflowã®ãã¹ãŠã®ãããã¯ã¯ããã©ã«ãã§ã·ã³ã°ã«ã¹ã¬ããã§ãã ã€ãŸã
ActionBlock ã
TransformerBlockãªã©ã¯ãã³ãŒã«ããã¯ã¡ãœããã1ã€ãã€åŒã³åºããŸãã TPL Dataflowã®äœæè
ã¯ãããã©ãŒãã³ã¹ã®åäžãããã·ã³ãã«ããéèŠã ãšèããŸããã ããŒã¿ãããŒã°ã©ãã«ã€ããŠèããã®ã¯éåžžã«é£ããããã¹ãŠã®ãããã¯ã§ããŒã¿ã䞊ååŠçãããšããã®ããã»ã¹ã¯ããã«é£ãããªããŸãã
䞊å床ã倿Žããã«ã¯ããããã¯ã¯
ExecutionDataflowBlockOptionsãæž¡ãã
MaxDegreeOfParallelismããããã£
ã 1ãã倧ããå€ã«èšå®ããå¿
èŠããããŸããã¡ãªã¿ã«ããã®ããããã£ã-1ã«èšå®ãããŠããå Žåããã¹ãŠã®çä¿¡èŠçŽ ã¯æ°ããã¿ã¹ã¯ã«ãã£ãŠåŠçããã䞊ååŠçã¯äœ¿çšãããã¿ã¹ã¯ã¹ã±ãžã¥ãŒã©ïŒ
TaskSchedulerãªããžã§ã¯ãïŒã®æ©èœã«ãã£ãŠã®ã¿å¶éãããŸã
ExecutionDataflowBlockOptionsãä»ããŠæž¡ãããšãã§ããŸãã
ãããã«
䜿ããããã³ã³ããŒãã³ãã®èšèšã¯å°é£ã§ãã äžŠè¡æ§ã®åé¡ã解決ãã䜿ããããã³ã³ããŒãã³ãã®èšèšã¯ãäºéã«é£ãããªããŸãã ãããã®ã³ã³ããŒãã³ããæ£ãã䜿çšããã«ã¯ããããã®å®è£
æ¹æ³ãšãéçºè
ã念é ã«çœ®ããŠããå¶éãç¥ãå¿
èŠããããŸãã
ActionBlock <T>ã¯ã©ã¹ã¯çŽ æŽããããã®ã§ããµãã©ã€ã€ãšã³ã³ã·ã¥ãŒãã®ãã¿ãŒã³ã®å®è£
ã倧å¹
ã«ç°¡çŽ åããŸãã ãã ãããã®å Žåã§ãã䞊å床ããªãŒããŒãããŒã®å Žåã®ãããã¯ã®åäœãªã©ãTPL Dataflowã®ããã€ãã®åŽé¢ã«ã€ããŠç¥ã£ãŠããå¿
èŠããããŸãã
-ïŒ*ïŒãã®äŸã¯ã¹ã¬ããã»ãŒãã§ã¯ãªããããå®å
šãªå®è£
ã§ã¯
actionBlock.InputCountã䜿çšããªãã§
ãã ãã ã åé¡ããããŸããïŒ
ïŒ**ïŒ
Postã¡ãœããã¯ã2ã€ã®ã±ãŒã¹ã®ããããã§
falseãè¿ããŸãããã¥ãŒããã£ã±ãã§ãããããã§ã«å®äºããŠããŸãïŒ
Completeã¡ãœãããåŒã³åºãããŸãïŒã ãããã®2ã€ã®ã±ãŒã¹ãåºå¥ã§ããªãããããã®åŽé¢ã¯ãã®æ¹æ³ã®äœ¿çšãè€éã«ããå¯èœæ§ããããŸãã äžæ¹ã
SendAsyncã¡ãœããã®åäœã¯å€å°ç°ãªããŸãããã®ã¡ãœããã¯ããã¥ãŒããã£ã±ãã®ãšãã«æªå®äºç¶æ
ã«ãªã
Task <bool>ãªããžã§ã¯ããè¿ããŸããããã¥ãŒãæ¢ã«å®äºããŠãããæ°ããèŠçŽ ãåãå
¥ããããšãã§ããªãå Žåã
task.Resultã¯
falseã«ãªã
ãŸã ã