Task サバイバル・ガイド

1 億 4 千万人の並行プログラミングファンのみなさんおはこんばんは*1
21 世紀に入り、C# でもやっと並行プログラミングがしやすくなりましたね*2

Task の使い方を書こうと思ったんだけど、なんていうか気分が乗らないのでやめとこーかなー。

と書いてやめようとすると書けるので書いてみる。

あるところに CreateTempla() という天ぷらオブジェクトを生成して返すメソッドがある:

Templa CreateTempla() {
    /* ... */
}

しかし、CreateTempla() は天ぷらを揚げるのでちょいと時間がかかる。
このために、Task を使いたい。

ということで、こう書いてみよう:

Task<Templa> CreateTemplaAsync() {
    /* ... */
}

待機可能なメソッドなので、Async をつけたよ。
使い方は簡単で、戻り値を受け取って天ぷらが揚がるまで待てばいいんだ。

// Task ちゃんに天ぷらを揚げてもらう。
var task = CreateTemplaAsync();

/* この間にトイレに行ったり、水を飲んだりする。 */

// やることが終わったので、天ぷらを食べる。
me.Eat( task.Result );

でも、どんな風に Task を使えばいいんだろう? ということで、TaskCompletionSource を使ってみよう:

Task<Templa> CreateTemplaAsync() {
    var completion_source = new TaskCompletionSource<Templa>();

    Task.StartNew( () => {
         /* 天ぷらを揚げる時間がかかる処理 */

         // 出来た天ぷらを Task#Result に設定する。
         completion_source.SetResult( templa )
    } );

    return completion_source.Task;
}

TaskCompletionSource を使うことで、ちょっとわかり易くなったんじゃないかな。

また次回!

*1:読者がいつ読んでいるか分からないのでいつ読まれてもいいような挨拶

*2:多分