深夜のasync/await談義

C# の新しい機能である、async/awaitがよくわからんかったので、識者の方に教えてもらってました。
12
neuecc @neuecc

@kaorun55 Task.Delayはそれ自身が非同期なので、awaitするか、.Waitで待つかしないと何も起こりませんよー

2012-03-15 00:50:18
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 例えばありがちなミスだと、コンソールアプリでawait Task.Delay してる非同期メソッド自体をWaitしてなくて、await完了する前にプログラムが終了しちゃってるとかは?

2012-03-15 00:53:32
中村 薫 @kaorun55

@neuecc そうなんですかぁ。その辺りが理解しきれてません。。。await すると、待つけど、しないと待たないのが

2012-03-15 00:53:43
neuecc @neuecc

@kaorun55 待つというか擬似的に待つ、です。それがawaitなんですね。あとContinueWithは概ねawaitに置き換えられると考えていいので、button1_Clickもasyncにしてしまうといいです。

2012-03-15 00:54:40
中村 薫 @kaorun55

@ufcpp 非同期メソッド自体は、待ってる気がするのですが、よくわからなくなってきました^^; さっきのお話は、少し理解できました https://t.co/6NFRndqF

2012-03-15 00:55:38
中村 薫 @kaorun55

@neuecc んー、もう少し考えてみます^^; ありがとうございます

2012-03-15 00:56:15
中村 薫 @kaorun55

絵に書いてみないとわからんかなぁ

2012-03-15 00:56:26
中村 薫 @kaorun55

んー、やっぱり、Task.Delayを理解するのがいいのか

2012-03-15 00:58:58
Kentaro Inomata @matarillo

@neuecc @kaorun55 awaitをつけると、後の処理が全部コールバックに置き換えられる感じですね。(なので待っているように見える)

2012-03-15 00:59:50
中村 薫 @kaorun55

@matarillo そっちはなんとか、わかってきました。awaitをつけない Task.Delay がまだわかりません(そもそも正しい使い方でない気もしますががが)

2012-03-15 01:01:03
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 await付けないと、fire and forget、その後のコールバック等一切呼ばないという状態になります。あとに何も続けないクセにタイマーだけ動く無駄状態。

2012-03-15 01:09:08
neuecc @neuecc

@hr_sao Taskにすると岩永さんと激しく被りそうなので、Rxでストリーム型の非同期処理とかそんな感じにしませう

2012-03-15 01:09:59
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 forkだけしてjoinがない状態という方がよいのかな<awaitしないDelay。分岐に。

2012-03-15 01:16:22
Kentaro Inomata @matarillo

@ufcpp @kaorun55 awaitをつけない場合は、戻り値のTaskのGetAwaiterメソッドを呼び出して、得られたTaskAwaiterにコールバックメソッドを登録して……という処理を自分で書かないと何も起きません。(awaitをつけるとコンパイラがやってくれる)

2012-03-15 01:17:06
中村 薫 @kaorun55

@matarillo @ufcpp あー、少しコールバックという意味が分かってきました。awaitってasyncメソッドの途中で戻すだけかと思ってたんですが、それだけでもないんですね。

2012-03-15 01:20:58
中村 薫 @kaorun55

@matarillo @ufcpp ついでの質問なんですけど、awaitで非同期になるのは、Task.Delayに限らず、awaitableのメソッド(async メソッド?)全般の話になるんですか?

2012-03-15 01:21:36
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 yield returnと一緒で、中断と再開です。再開するのが、Delay完了してから(コールバックで続きから再開)。

2012-03-15 01:22:58
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 Awaiterの実装次第ですが、例えばTaskを返すメソッドなら(TaskのAwaiterは)もちろん全部非同期です。ただし、TaskがすでにIsCompleteなら別にコールバックみたいなことはせずその場で続行する作りになっています。

2012-03-15 01:24:08
中村 薫 @kaorun55

@ufcpp @matarillo あー、すこしずつわかってきました^^; http://t.co/gpTcRTx9

2012-03-15 01:39:19
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 てか、それだと、button1_Click自体にasyncを付けて、var someTaskの行はawait slowFunc(1, 2); だけにすべきですねぇ。ContinueWith不要。同期コンテキストの指定も不要(awaitが勝手にやる)。

2012-03-15 01:43:04
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 ちなみに、awaitの仕組みと似たようなものを自作するなら http://t.co/ysZsUGsp このような感じに。ほんとに、yield returnの生成結果に近いです。

2012-03-15 01:46:38
中村 薫 @kaorun55

@ufcpp あー、なるほど。さっきも、そんな指摘をいただきました。とりあえず、async/awaitの動きを知りたかったので、いまはこんな感じですー

2012-03-15 01:47:48
中村 薫 @kaorun55

[C#] / “Program.cs - C# Async の例 - Sample Code - MSDN Examples in C#, http://t.co/wwCwJ9Kx, C++, JavaScript, F#” http://t.co/2xD7eyvB

2012-03-15 01:48:53
++C++; // 管理人: 岩永 @ufcpp

@kaorun55 今の状態だとTask.Factory.Startしてしまってる(その先でawaitしてない)ので、別スレッドで待っちゃってるので意味なくなってますねぇ。

2012-03-15 01:48:57