++C++; // 未確認飛行 C ブログ

http://ufcpp.net/

Async C#/VB

with one comment

ようやく、C#/VB にも非同期構文が入るようです。

http://msdn.microsoft.com/vstudio/async

  • C#/VB に非同期用の構文が入ります
    • async キーワードで非同期呼び出し開始、await キーワードで計算結果を拾えるっぽい
    • 基本的には Task クラスに対する構文糖衣になる模様
  • あと、VB にイテレーター ブロックが追加
    • しかも、VB は匿名メソッド中でも Yield 書ける
  • バージョンや時期に関しては一切触れられておらず
    • これだけが C# 5.0 でもないってことかな?
    • C# 5.0 ⊃ Async CTP な包含関係?

関連リンク:

Async CTP 以外の情報

Anders Hejlsberg の The Future of C# and Visual Basic では、大部分 Async CTP の話ですけども、最後にちょこっと Compiler as a Service の進捗状況のデモが。

  • デモ失敗してたんで、やっぱりまだまだ安定しえない感じで、いつになる分からない状況
  • Visual Studio との連携されてる
    • 最近ずっと言ってる「DSL 作るなら IDE との連携まで考えないとダメ」ってのが、ちゃんと実現できそうな感じ

あと、この発表を見て、「Reactive Extensions (Rx)はどうなるの?」みたいな話も出てますね。とりあえず、今のところ、

  • 単一の値を非同期にとってきて処理 → async
  • 定常的にやってくる非同期イベントを処理しつづけたい → Rx

という認識でよいかと。こっちはこっちで、以下の動画参照

ちなみに、RX も今日、更新: Release Notes

Async CTP の大まかなイメージ

以下のような非同期メソッドを書いて、

static async void TestAsync()
{
    for (int i = 0; i < 5; i++)
    {
        Console.WriteLine(i);
        await TaskEx.Delay(1000);
        Console.WriteLine("end test");
    }
}

Main メソッドで以下のように書くのと

TestAsync();
Thread.Sleep(5000);
Console.WriteLine("Main 終了");

以下のようなイテレーター + 補助関数を書いて

static void Async(IEnumerable<object> coroutine)
{
    var e = coroutine.GetEnumerator();
    Action a = null;
    a = () =>
    {
        lock(e) if (!e.MoveNext()) return;
        a.BeginInvoke(ar => { a(); }, null);
    };
    a();
}

static IEnumerable<object> Coroutine()
{
    for (int i = 0; i < 5; i++)
    {
        Console.WriteLine(i);
        TaskEx.Delay(1000).Wait();
        yield return null;
    }
    Console.WriteLine("end test");
    yield return null;
}

以下のように呼び出すのが

Async(Coroutine());
Thread.Sleep(5000);
Console.WriteLine("Main 終了");

同じような動作をするイメージ。(あくまでイメージ。これだと例外に対処できてない。)

(あっ、あと、Task の Wait の位置おかしい。yield return の後で Wait しないと。< あとで直す)

  • イテレーターと同じようなノリで結構頑張ってコード生成。
    • await のところでいったん BeginAwait(); return; して処理を止めて、次の MoveNext(相当の呼び出し)のときに EndAwait(); してから再開。
    • こういうアイディアでやってるって話、実は PDC の前日にブログ記事が上がってたり:
  • そのイテレーター的なものを、何度も細切れに、MoveNext が false になるまで非同期呼び出し
  • await できるためには、GetAwaiter メソッドを持っていて、その戻り値(awaiter)が BeginAwait と EndAwait を持ってないとダメ。
    • GetAwaiter は拡張メソッドでも OK っぽい。

構文的には、最近では結構よくみる非同期構文なんですが、

  • 極力フレームワーク(既存の Task クラス)に頼る
  • 拡張メソッドも含めて、規約ベースの構文糖衣
    • LINQ のクエリ式で、 from x in list where x > 0 select x が list.Where(x => x > 0) と解釈されて、Where はインスタンス メソッドでも拡張メソッドでもいいというのと同様

というように、コンパイラーへの負担を最小に抑えているのがポイント。おかげで、以下の通り、仕様書が Word 形式で10ページ(53KB)というコンパクトさ。

広告

Written by ufcpp

2010年10月28日 @ 19:42

カテゴリー: .NET, C#

Tagged with , ,

コメント / トラックバック1件

Subscribe to comments with RSS.

  1. Async C#/VB…

    素敵なエントリーの登録ありがとうございます – .NET Clipsからのトラックバック…

    .NET Clips

    2010年10月29日 at 15:46


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。