CïŒ5ã®async / awaitã«é¢ãã以åã®ã¡ã¢ïŒ
ããŒãI ã
ããŒãII ïŒã§ãHaskellãFïŒãNemerleãªã©ã®èšèªã§åæ§ã®ã¢ãããŒããå®è£
ãããŠããããšãæžããŸããããCïŒãšã¯ç°ãªãããããã®èšèªã¯é«ã¬ãã«ã®æŠå¿µããµããŒãããŠããŸããããã«ãããèšèªã¬ãã«ã§ã¯ãªãã©ã€ãã©ãªãšããŠasync / awaitã®ã¹ã¿ã€ã«ã§éåæèšç®ãå®è£
ã§ããŸãã Nemerleã§ã¯ããã®ã³ã³ã»ããèªäœãã©ã€ãã©ãªãšããŠå®è£
ãããŠããã®ã¯é¢çœãã§ãã ãã®æŠå¿µã®ååã¯ã¢ããã§ãã éåæèšç®ã«å ããŠãã¢ããã䜿çšãããšããªã¹ãã®ç解ãç¶ç¶ãããŒãã£ãªé¢æ°ãã¯ãªãŒã³ãªãããã¯ã«å€æããç¶æ
ãæé»çã«ãã©ãã°ãããªã©ãä»ã®å€ãã®å©ç¹ãå®è£
ã§ããŸãã
äžéšã®ã¢ããã¯ãCïŒããã°ã©ãã®ãåžæããyieldã³ã¬ã¯ã·ã§ã³ãŸãã¯yield foreachããã³lambdaåŒããyieldãšããŠå®è£
ããŸãã
ãã®æçš¿ã®ç®çã¯ãNemerleãéåæããã°ã©ãã³ã°ããã³èšç®åŒã«å°å
¥ããããšã§ãããFïŒãåŠç¿ããŠãã人ã«ãšã£ãŠã圹ç«ã€å¯èœæ§ããããããNemerleã§ã®éåæããã°ã©ãã³ã°ã®å®è£
ã¯ãFïŒã«æ³šç®ããŠè¡ãããŸããã äžæ¹ãä»ã®èšèªã®åé¡ã§ããããã€ãã®ã¿ã¹ã¯ïŒ
ãã¹ãŠã®éåæåŒã³åºãã®åŸ ïŒãã2ã3è¡ã®èšç®åŒã䜿çšããŠã©ã®ããã«è§£æ±ºããããã¯ã誰ãã«ãšã£ãŠèå³æ·±ããããããŸããã
ãããããã¢ãããšã¯äœããç解ããŠãã人ã¯èª°ã§ããã¢ãããšã¯äœãã«ã€ããŠã®èšäºãæžããŠããã§ãããã ç§ãäŸå€ã§ã¯ãããŸããã§ããã ä»ã®äººããããªããã¬ãŒã·ã§ã³ãç解ã§ããäžæ¹ã§ãç¥ã£ãŠãã人ãèŠããŠããããã«ãã§ããã ãç°¡æœã«èª¬æããããã«ããŸãã
ã¢ãã
ã¢ããã¯ãèšèªã«ãµããŒããçµã¿èŸŒãŸããŠããçæãã¿ãŒã³ã§ãã 次ã®ãã¢ããã®ãã¿ãŒã³ã®äžå¿ã«ãããŸãã
å€çžå
interface F<T> { ... }
圌ã«å¯Ÿããããã€ãã®æäœ
class M { static public F<T> Return<T>(T obj) { ... } static F<U> Bind<T,U>(F<T> obj, Func<T, F<U>> fun) { ... } }
Returnã䜿çšãããšãã¢ããå
ã®ä»»æã®å€ããã©ããããããã€ã³ãããŠãã®äžã§å€æãå®è¡ã§ããŸãã StringBuilderã䜿çšããŠéåžžã«åŒ±ãé¡äŒŒæ§ãåŒãåºãããšãã§ããŸãããã®ã³ã³ã¹ãã©ã¯ã¿ãŒã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãã©ã¡ãŒã¿ãŒã§åæå€ãæž¡ããAppend *ã¡ãœããã§å€æŽããŸãã
FãIEnumerableã§çœ®ãæããå Žåããã€ã³ã眲åã¯Linq SelectMany眲åã«äŒŒãŠããŸãã ããã¯é©ãã¹ãããšã§ã¯ãããŸããããšããã®ããLinqãçŽ æŽãããäºçŽãããŠããã®ã§ãã¢ããã ããã§ãã ã¡ãªã¿ã«ãPDC2010ã§ã¯ãããŒããã¹ã¡ããããLINQãTake Two-Realizing the LINQ to Everything Dreamããšããã¬ããŒãã§èå³æ·±ã話ãããŸããïŒ
ãªã³ã¯ ïŒã
Linqãã¢ããã®å ŽåãåçŽãªLinqåŒãäœæããŠã¿ãŠãã ããã
var nums = Enumerable.Range(-2, 7); var sqrt = from n in nums where n >=0 select Math.Sqrt(n);
Mæäœã䜿çšããŸãã æåã«ãMæäœã宣èšããŸãã
static class MList { static public IEnumerable<T> Return<T>(T obj) { var list = new List<T>(); list.Add(obj); return list; } static public IEnumerable<U> Bind<T, U>(this IEnumerable<T> obj, Func<T, IEnumerable<U>> fun) { return obj.SelectMany(fun); } static public IEnumerable<T> Empty<T>() { return Enumerable.Empty<T>(); } }
ãããŠãLinqåŒãæžãçŽããŸãïŒ
var nums = Enumerable.Range(-2, 7); var sqrt = nums .Bind(n => n >= 0 ? MList.Return(n) : MList.Empty<int>()) .Bind(n => MList.Return(Math.Sqrt(n)));
Linqã®å Žåãããããã«æªåããŸããããããã¯ã¢ãããµããŒããCïŒã«çµã¿èŸŒãŸããŠããªãããã§ãã Nemerleã®å Žåããã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããMæäœã宣èšããŸãã
class MList { public Return[T](obj : T) : IEnumerable[T] { def data = List(); data.Add(obj); data } public Bind[T, U](obj : IEnumerable[T], f : T->IEnumerable[U]) : IEnumerable[U] { obj.SelectMany(f) } public Empty[T]() : IEnumerable[T] { Enumerable.Empty() } }
ãããŠãLinqåŒãæžãçŽããŸãïŒ
def mlist = MList(); def nums = Enumerable.Range(-2, 7); def sqrt = comp mlist { defcomp n = nums; defcomp n = if (n >= 0) mlist.Return(n) else mlist.Empty(); return Math.Sqrt(n :> double); };
æåã«ãNemerleã®defã¯CïŒã®varã®ç§»æ€æ§ã®ãªãé¡äŒŒç©ã§ãããifã¯äžé
æŒç®åïŒïŒ:)ã§ãããã³ã³ã¹ãã©ã¯ã¿ãŒã®åŒã³åºãã«ã¯newã¯å¿
èŠãªãããšãæãåºããŠãã ããã ãããŸã§ã®ãšãããcompæŒç®åã¯ã¢ããèšç®ã®éå§ãã¢ããŠã³ã¹ãã次ã®ãã©ã¡ãŒã¿ãŒã¯MæäœãæäŸããèšç®èªäœãç¶è¡ãããŸãã
Linqãšæ¯èŒãããšã1è¡ã§ã¯ãªã3è¡ã§ããããããã®è¡ã¯1ã€ã®å€æ°ã§æ©èœããéåžžã®ã³ãŒãã®ããã«èŠããå®éã«ã¯å
ã®ã³ã¬ã¯ã·ã§ã³ããæ°ããã³ã¬ã¯ã·ã§ã³ãçæããŸãã ãã®äŸã¯æè²ç®çã§æäŸãããŠããŸãã以äžã¯ãéåžžã®ã³ãŒãã§ã¯ç¹°ãè¿ãã®ãéåžžã«é£ããäŸã§ãã ä»çµã¿ãèŠãŠã¿ãŸãããã
defcompã¯ãã¢ããïŒãã®å ŽåãIEnumerable [T]åïŒãïŒTåã®ïŒå€ã«ãå€æãããéã«å€ãã¢ããã«å€æããããžãã¯ãªãã¬ãŒã¿ãŒã§ãã å®éãéæ³ã¯ãªãããã ã®è¡šçŸã§ã
defcomp n = nums; ...
ã³ã³ãã€ã©ã«ãã£ãŠæ¡åŒµããã
mlist.Bind(nums, n => ...)
èšç®åŒ
Haskellèšèªã«ã€ããŠè°è«ããŠããã®ã§ããã°ãã¢ããã«ã€ããŠã®è©±ã¯ããã§çµãããŸãã ãããããã€ããªããèšèªïŒé¢æ°å/åœä»€åïŒã®å Žåãæ¡ä»¶æŒç®åãã«ãŒããããã³yieldãªã©ã®å¶åŸ¡æ§é ãååšãããããç¶æ³ã¯ããå°ãè€éã§ãã ãããã©ã®ããã«åé¡ãåŒãèµ·ããããç解ããããã«ãMæŒç®ãéãã«ãŒããšã«ãŒãå
ã®defcompæŒç®åãå«ãã¢ããèšç®ãè¡šçŸããããšãã§ããŸãã
ãã®åé¡ã®è§£æ±ºæ³ã¯éåžžã«ç°¡åã§ããããšãã°ããã©ã³ãæŒç®åãšã«ãŒãã®å€æãåŠçããMæäœã¡ãœããã®ã»ããã«è¿œå ããå¿
èŠããããŸãããWhââileã«ã¯æ¬¡ã®ã·ã°ããã£ããããŸãã
public F<FakeVoid> While<T>(Func<bool> cond, Func<F<FakeVoid>> body)
ã³ã³ãã€ã©ãæ¬äœã«ã¢ããæŒç®åãå«ãã«ãŒããæ€åºãããšãæåã«ã«ãŒãæ¬äœããã€ã³ããã§ãŒã³ã«å€æããŸããBindã¯F <T>ãè¿ãããããã®ãã§ãŒã³ã¯ã©ã ã "ïŒïŒ=> bodyïŒïŒ"ã§ã©ããã§ããŸãã Func <F <T >>ã®å Žåãã³ã³ãã€ã©ãŒã¯ã«ãŒãæ¡ä»¶ãã©ã ãã§ã©ãããããããã®ã©ã ããMæäœã®Whileã«æž¡ããŸãã
åMæäœã¯ã¢ãããè¿ãå¿
èŠããããŸãããã«ãŒãã¯äœãè¿ããŸããããããã£ãŠãã¢ããã«ã©ããã§ããå€ã¯ãããŸããã ãããã®ç®çã®ããã«ãFakeVoidã¿ã€ãã®ã·ã³ã°ã«ãã³ã䜿çšãããŸãã
ããã§ãèšç®åŒã®éå
¬åŒãªèª¬æãã§ããŸããããã¯ãåœä»€åèšèªã®ã¢ããã§ãã a-la haskellã®å Žåãã³ã³ãã€ã©ãŒã¯defcompãæžãæããŠãåé
èšç®ã®å
éšã§è¿ãã ãã§ããåœä»€åèšèªã®å Žåã«æ¢ã«è¿°ã¹ãããã«ãå¶åŸ¡æ§é ãæžãæããããŸãã以äžã®è¡šã«ã¯ãæžãæãããããã¹ãŠã®æŒç®åããããŸãã
defcomp | æå³ã§ã¢ãããæ¡åŒµããå²ãåœãŠã«è¿ãæå³ |
callcomp | å€ãéèŠã§ãªããšãã«äœ¿çšãããã¢ãããå±éããŸã |
åž°ã | åŒæ°ãã¢ããã«ã©ããããã¢ããèšç®ã®ãããã¯ã®æåŸã§äœ¿çšãããŸããæå³ã¯é¢æ°ããæ»ãããšã«è¿ã |
returncomp | åŒæ°ã¯ã¢ããã§ãããã¢ããèšç®ã®ãããã¯ã®çµæãšããŠãã®ã¢ãããè¿ããŸããæ»ããšã¯ç°ãªããå床ã©ããããŸãã |
å©åã | åŒæ°ãã¢ããã«ã©ããããreturn returnã«äŒŒãã¢ã¯ã·ã§ã³ãå®è¡ããŸã |
yieldcomp | åŒæ°-ã¢ãããyieldãåŒæ°ãå床ã©ããããªãã®ãšã¯ç°ãªããyield returnãšåæ§ã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸã |
ifãwhenãunlessãwhileãdoãforeachãforãusingãtry ... catch ... finally | éåžžã®å¶åŸ¡æ§é ã®åé
ããŒãžã§ã³ |
Mãªãã¬ãŒã·ã§ã³ã®ãããã€ããŒã«ã€ããŠããå°ã説æããŸãã å
¬åŒã«ã¯ããããã¯ãã«ããŒãšåŒã°ããèšç®åŒãäœæãããšãã«ã¢ãã«ã®åä»ãã䜿çšãããŸããã€ãŸãããã«ããŒã¯ã³ã³ãã€ã©ãŒã䜿çšããã¡ãœãããå«ãå¿
èŠããããŸããããã«ããŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããå¿
èŠã¯ãããŸããã ãã®ãœãªã¥ãŒã·ã§ã³ã䜿çšãããšãèšç®åŒã§ãã¹ãŠã®æ©èœã䜿çšããäºå®ããªãå Žåã«ããã«ããŒãéšåçã«å®è£
ã§ããŸãã ãšããã§ãMListãã«ããŒãäœæãããšãã«ãã®ã¢ãããŒããæ¢ã«äœ¿çšããŸããïŒdefcompãšreturnã®ãµããŒãã®ã¿ãå®è£
ãããŠããŸãïŒã
ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããªããã1ã€ã®çç±ã¯ãMæäœã®çœ²åã«ããå³ããæ¡ä»¶ã課ãããšã§ãã ã¿ã€ãããšã®ã¢ãããšMæäœã®äºææ§ã®ã¿ãå¿
èŠã§ãã ããšãã°ãäžèšã®äŸã§ã¯ãã¢ããã«ã¯1ã€ã®ãžã§ããªãã¯ãã©ã¡ãŒã¿ãŒããããšæ³å®ãããŠããŸããããããã€ãã®ãã©ã¡ãŒã¿ãŒãç°¡åã«æã€ããšãã§ããŸããããã«ãã¬ãŒã·ã§ã³ãä»ããããšã¯éèŠã§ã¯ãããŸããããããã¯
Continuationã¢ããã®äŸã䜿çšããŠèª¿ã¹ãããšãã§ããŸãã
ç¬èªã®ãã«ããŒãäœæããå Žåã¯ã
èšç®åŒã®ãœãŒã¹ã調ã¹ãããšããå§ãã
ãŸã ã
æšæºãã«ããŒã®äŸ
æšæºãã«ããŒã¯èšç®åŒã©ã€ãã©ãªã«çµã¿èŸŒãŸããŠãããããã€ã³ã¹ã¿ã³ã¹ãäœæããŠcompããã©ã¡ãŒã¿ãŒãšããŠæž¡ã代ããã«ãååããã©ã¡ãŒã¿ãŒãšããŠæž¡ãã ãã§ååã§ãã
äžèŠ§
ãªã¹ããã«ããŒã¯ãèšèªã®æšæºå¶åŸ¡æ§æäœãããã³yieldããã³yieldcompããµããŒãããŸãã ãªã¹ã[T]ïŒNemerleã®æšæºãªã¹ãïŒãã¢ãããšããŠäœ¿çšããŸãã ãã®ãã«ããŒã¯ãCïŒããã°ã©ããŒã®2ã€ã®é·å¹Žã®ããŠã£ãã·ã¥ãªã¹ãããå®è£
ããŠãããšããç¹ã§èå³æ·±ããã®ã§ããlambdafrom lambdaãšyieldã³ã¬ã¯ã·ã§ã³ã§ãã æåã«ãèšäºã®æåããã®Linqã¯ãšãªã¢ããã°ãèŠãŠã¿ãŸãããã
def num = Enumerable.Range(-2, 7); def sqrt : list[double] = comp list { foreach(n in num) when(n >= 0) yield Math.Sqrt(n); }
ã芧ã®ãšããããªã¹ããã«ããŒã䜿çšãããšãé¢æ°ã宣èšããããšãªãyieldåŒã䜿çšã§ããŸãããŸãããªããžã§ã¯ããžã®ãªã³ã¯ã®ä»£ããã«äœ¿çšããããšãã§ããŸãã ãã®ã³ãŒãã¯ãåçã®linqåŒãããèªã¿ããããšæãããŸãã
次ã«ãå¥ã®ããŠã£ãã·ã¥ãªã¹ãããæ€èšããŸããã³ã¬ã¯ã·ã§ã³ãçæããŸããæåã«ã·ãŒã±ã³ã¹ãçæããããŒã«ã«é¢æ°ã宣èšããããã2ååŒã³åºããŠã³ã¬ã¯ã·ã§ã³ãçæããŸãã
def upTo(n) { comp list { for(mutable i=0;i<n;i++) yield i } } def twice = comp list { repeat(2) yieldcomp upTo(3); } Console.WriteLine(twice); //[0, 1, 2, 0, 1, 2]
ç§ã¯èªåã®ãžã§ãã¬ãŒã¿ãŒãæžãå¿
èŠããããåã®ããã«ãEnumerable.RangeïŒ0ã3ïŒãã䜿çšããŸããã§ããïŒyieldcompã¯ã¢ãããå
¥åãããããšãæåŸ
ãããã®å Žåã®åã¯ãªã¹ã[int]ãããã³ãEnumerable.RangeïŒ0ã3ïŒ ãIEnumerable [int]ãè¿ããŸãã ãã®ççŸãå
æããããã«ãåæå¯èœãªå¥ã®ãã«ããŒããããŸãã
åæå¯èœ
ãã®ãã«ããŒã¯ãListãã«ããŒãã»ãŒç¹°ãè¿ããã¢ããã®ã¿ã€ããšããŠIEnumerable [T]ã®ã¿ã䜿çšããç¡éã·ãŒã±ã³ã¹ãæ§ç¯ã§ããŸãã æåŸã®äŸãæžãçŽããŸãã
def twice = comp enumerable { repeat(2) yieldcomp Enumerable.Range(0, 3); } foreach(item in twice) Console.Write($"$item "); //0, 1, 2, 0, 1, 2
é
å
listããã³enumerableãšåæ§ã«ãé
åã¯åäœããã¢ããã®ã¿ã€ããšããŠé
å[T]ã®ã¿ã䜿çšããŸãã
éåæ
æãè€éã§ããéåžžã«äŸ¿å©ãªãã«ããŒã¯ãå€ãã®ç¹ã§CïŒã®å°æ¥ã®éåæ/åŸ
æ©ã«äŒŒãŠããŸãã æ¢åã®éåæã³ã³ãã¥ãŒãã£ã³ã°ãçµã¿åãããŠãéåæã³ã³ãã¥ãŒãã£ã³ã°ãæ§ç¯ããããã«äœ¿çšãããŸãã
yieldãšyieldcompãé€ããã¹ãŠã®æäœããµããŒãããŸãã
ãã®ãã«ããŒã®ã¢ããåã¯Async [T]ã§ãã ãã®ã¿ã€ãã®ãªããžã§ã¯ãã¯éåæèšç®ãèšè¿°ãããã®çµæã¯ã¿ã€ãTã®å€ã«ãªããŸãïŒCïŒã®Task <T>ãªã©ïŒãéåææäœãå€ãè¿ããªãå ŽåãTã®ä»£ããã«ç¹å®ã®FakeVoidã¿ã€ãã䜿çšãããŸãã ãã€ã³ãæäœããã®ã¿ã€ãAsync [T] *ïŒT-> Async [U]ïŒ-> Async [U]ã¯ãé¢æ°ã«ããïŒAsync [T]ã¿ã€ãã®ïŒéåæèšç®ããç¶ç¶ããããã®é¢æ°ã¯ã¿ã€ãTã®ãªããžã§ã¯ããå
¥åïŒçµæéåæèšç®ïŒãAsync [U]ã¿ã€ãã®æ°ããéåæèšç®ãè¿ããŸãã
ãã1ã€ã®ããŒã¿ã€ãã¯æœè±¡ã¯ã©ã¹ExecutionContextã§ãããã®åå«ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãéåææäœïŒããšãã°ãçŸåšã®ã¹ã¬ãããThreadPoolã®ã¹ã¬ããããŸãã¯SynchronizationContextã®äœ¿çšïŒã®éå§ãæ
åœããŸãã眲åã¯æ¬¡ã®ãšããã§ãã
public abstract class ExecutionContext { public abstract Execute(computatuion : void -> void) : void; }
éåææäœãéå§ããã«ã¯ãéåææäœãèšè¿°ãããªããžã§ã¯ãã®Startã¡ãœããïŒã¯ã©ã¹Async [T]ïŒãåŒã³åºããŠãExecutionContextåã®ãªããžã§ã¯ããæž¡ãå¿
èŠããããŸããã¡ãœãããåŒæ°ãªãã§åŒã³åºãããå Žåãéåææäœã¯ThreadPool.QueueUserWorkItemã䜿çšããŠéå§ãããŸãã
CïŒã§éåæ/åŸ
æ©å®è£
ã䜿çšã§ããæ¡åŒµæ©èœïŒéåæCTPïŒã«ã¯ãæ¢åã®ã¯ã©ã¹ãéåææäœã§è£å®ããå€ãã®æ¡åŒµã¡ãœãããæ¢ã«ãããŸãã éåæã¯ãã¢ããå®è£
ã䜿çšããŠã©ã€ãã©ãªã«ãã®ãããªæ¡åŒµæ©èœãæäŸããŸããããæ¢åã®ããªããã£ãã«åºã¥ããŠããããæ§ç¯ããç°¡åãªæ¹æ³ãæäŸããŸãã ããšãã°ããã¬ãŒã ã¯ãŒã¯ã®æåã®ããŒãžã§ã³ããååšãããªã¯ãšã¹ããéåæçã«å®è¡ããæ¢åã®HttpWebRequest眲åã®äžéšãèããŠã¿ãŸãããã
public class HttpWebRequest : WebRequest, ISerializable { public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state); public override WebResponse EndGetResponse(IAsyncResult asyncResult); }
次ã«ããããã®ããªããã£ãã䜿çšããã¢ããã³ã³ãã¥ãŒãã£ã³ã°ã§ã®äœ¿çšã«é©ããéåææ¡åŒµãäœæããŸãã
public module AsyncExtentions { public GetResponseAsync(this request : HttpWebRequest) : Async[WebResponse] { Async.FromBeginEnd(request.BeginGetResponse(_, null), request.EndGetResponse(_)) } }
Nemerleã®_ã¯ç¹æ®æåã§ããããã®å Žåã¯ã«ãªãŒåã䜿çšãããããšãæãåºããŠãã ããïŒè¡šèšfïŒ_ïŒã¯x => fïŒxïŒãšåçã§ãïŒã åæ§ã«ãæšæºã®éåæèšç®çšã®ã©ãããŒãäœæã§ããŸãã
Nemerleã®ïŒCïŒ101ïŒéåæãµã³ãã«ããäœããæžããŸããããããšãã°ãè€æ°ã®WebããŒãžã䞊è¡ããŠèªã¿èŸŒã¿ãã¿ã€ãã«ãå°å·ããŸããGetHtmlïŒïŒããã³GetTitleïŒïŒæ¡åŒµã³ãŒããçç¥ããŸãããèšäºã¯æ¢ã«ãã©ãã°ãããŠããŸãã
public PrintTitles() : Async[FakeVoid] { comp async { def response1 = HttpWebRequest.Create("http://www.ya.ru").GetResponseAsync(); def response2 = HttpWebRequest.Create("http://www.habr.ru").GetResponseAsync(); defcomp response1 = response1; defcomp response2 = response2; Console.WriteLine(response1.GetHtml().GetTitle()); Console.WriteLine(response2.GetHtml().GetTitle()); } }
æåã®2è¡ã§ã¯ãéåæããŒãžèªã¿èŸŒã¿æäœãéå§ããããããã®ã¡ãœããã¯å®è¡æã«éåææäœãèšè¿°ãããªããžã§ã¯ããè¿ããŸããã³ã³ãã€ã©ã®èŠ³ç¹ããã¯ããããã®ãªããžã§ã¯ãã®ã¿ã€ãã¯Async [WebResponce]ïŒmonadïŒã§ãã 次ã®2è¡ã§ã¯ãæå³ã®ã¢ãããæ¡åŒµãããŸããæå³ã®å¥ã®ã¬ãã«ã§ã¯ãçµæã®æåŸ
ãæå³ããŸãã æåŸã®è¡ã§ã¯ãçµæãåŠçãããŸãã
ãããããããšã«ãJavaScriptã§è¡ãæ£ããæ¹æ³ïŒ
ãã¹ãŠã®éåæåŒã³åºãã®çµæãåŸ
ã€ïŒã«ã€ããŠã®è°è«ãéåžžã«æãã£ãããšãããããŸããããæ°ã«å
¥ã90ãã³ã¡ã³ã100ã§ãã ããããäŸã«æ»ããŸãããã
èŠããŠããã¹ãäž»ãªããšã¯ãã¢ããã¯çæãã¿ãŒã³ã§ãããéåæèšç®ãèšè¿°ããé¢æ°ãäœæãããããããéå§ãããPrintTitlesïŒïŒãStartïŒïŒãGetResultïŒïŒã®ããã«å®è¡ã§ããããšã§ãã
å®éãããã¯éåžžã«éèŠã§ãããšã©ãŒã®åå ã«ãªãå¯èœæ§ããããããã¡ãœãããAsync [T]ãè¿ãå Žåããã®ã³ãŒããèšç®ãéå§ããã®ãããããæ§ç¯ããã ããªã®ããèªèããå¿
èŠããããŸã ã åºå¥ããããã«ãããããåœåèŠåã䜿çšãã䟡å€ããããŸããããšãã°ãã³ã³ãã¥ãŒãã£ã³ã°ãéå§ããã¡ãœããã«ã¯éåæãµãã£ãã¯ã¹ãå¿
èŠã§ãã
CïŒã®async / awaitã«é¢ãã2çªç®ã®èšäºã§ãawaitã¯éåæèšç®ãéå§ããã¹ã¬ããã®SynchronizationContextã§éåæèšç®ã®çµæã®åŠçãéå§ããããšãæžããŸããã Nemerleã¯ãã®ç¹ã«é¢ããŠéåžžã«æè»æ§ããããã¹ã¬ããéã§èšç®ã転éããããšãã§ããŸãã ãã¿ã³ã¯ãªãã¯ãã³ãã©ãŒãèããŸãã
private button1_Click (sender : object, e : System.EventArgs) : void { def formContext = SystemExecutionContexts.FromCurrentSynchronizationContext(); def task = comp async { Thread.Sleep(5000); callcomp Async.SwitchTo(formContext); label1.Text = "success"; } _ = task.Start(SystemExecutionContexts.ThreadPool()); }
ãŸããçŸåšã®SynchronizationContextã§èšç®ãéå§ããExecutionContextãååŸãã次ã«éåææäœãèšè¿°ããŸãïŒThread.Sleepã¯éãèšç®ããšãã¥ã¬ãŒãããå®è¡ã³ã³ããã¹ããã¹ã¬ããã®å®è¡ã³ã³ããã¹ãguiã«åãæ¿ããŠçµæã衚瀺ããŸãã èšç®èªäœã¯ãExecutionContextsã¹ã¬ããããŒã«ã§èµ·åãããŸãã
ããã¯éæ³ã®ããã«èŠããŸãããå®éã«ã¯ãã¹ãŠããã§ã«èµ·ãã£ãŠããããã®æå³ãéèŠã§ãªãå Žåãcallcompã¯åã«ã¢ãããæããã«ããŸãã ãããããªããããé瀺ããã®ã§ããããïŒ ããã¯å¯äœçšãšç¶æ
ã®åé¡ã§ãããã¢ããã®æäœäžã«ç¶æ
ãããããä»ããŠãã©ãã°ããããªãŒãã³æã®ã¢ããã¯ãã®ç¶æ
ã«ã¢ã¯ã»ã¹ãããããå€æŽããããšãã§ããŸãã ãã®äŸã§ã¯ãç¶æ
ã¯ã³ãŒããå®è¡ããã³ã³ããã¹ãã®æ
å ±ãä¿åãããã®æ
å ±ãå€æŽããããšãæ°ããã³ã³ããã¹ãã«åãæ¿ãããŸãã 詳现ã«ã€ããŠã¯ã
ãœãŒã¹ãèªãããšããå§ãããŸããèå³æ·±ãã§ãã
Async.SwitchToã«å ããŠãå®è¡ã®ãããŒã«åœ±é¿ãäžããä»ã®èå³æ·±ãã¢ããããããŸããããšãã°ãAsync.Yieldã¯ãå®è¡ã³ã³ããã¹ãã¯å€æŽãããŸããããå®è¡ã³ã³ããã¹ããå€æŽãããããšã瀺ããŸãã å Žåã«ãã£ãŠã¯ãããã¯äœãè¡ããŸãããThreadPoolã䜿çšãããå Žåããã®ã¢ã¯ã·ã§ã³ã¯ããŒã«ããå¥ã®ã¹ã¬ãããžã®ãžã£ã³ããåŒãèµ·ãããŸãã
ãããã«
çµè«ãšããŠãç§ã¯ã¢ãããéåžžã«è±å¯ãªãããã¯ã§ããããšã«ã®ã¿æ³šæããããšãã§ããŸãã ãã®èšäºã§ã¯ãStateãContïŒç¶ãïŒãMaybeïŒå¥ã®CïŒãã¡ã³ããŒã€ãŠã£ãã·ã¥ãªã¹ãïŒãªã©ã®å€å
žçãªã¢ããã«ã¯è§ŠããŸããã§ããã ãããã«ã€ããŠã¯ä»ã®èšäºã§èªãããšãã§ããŸããç§ã¯å®çšçãªèª¬æãããããšããŸããããããã§Nemerleã§éåæããã°ã©ãã³ã°ãšãªã¹ã/åæå¯èœãªã¢ããã䜿ãå§ããå
éšã§äœãèµ·ãã£ãŠããã®ããç¥ãããšãã§ããŸãã
å€ãã®ç¹ã§ãå°æ¥ã®CïŒã§ã®await / asyncã®å®è£
ãšNemerleã§ã®éåæããã°ã©ãã³ã°ãžã®ã¢ããã®ã¢ãããŒãã¯äŒŒãŠããŸãããawait / asyncããµããŒãããããã®æ³šæç¹ã1ã€ãããŸãã次ã®ããŒãžã§ã³ã®èšèªãå¿
èŠã§ããèšèªã§ã¯ãªãèšèªïŒã
ç§ã¯è³ªåã«ã³ã¡ã³ãããŠçããŠããããã§ãã