[C#]async/awaitの使い方メモ、その1。

今後の.NET開発では必須スキルか。
.NETでの非同期処理の書き方があまりにも色々ありすぎて覚えるのも大変。でも、async/awaitを使用した非同期処理は今後重要なキーワードとなってきそうです。

参考
連載:C# 5.0&VB 11.0新機能「async/await非同期メソッド」入門
http://www.atmarkit.co.jp/ait/subtop/features/da/ap_masterasync_index.html

ボタンをクリックすると1秒間隔でラベルの文字が変更するプログラムを書く。
フォームのボタンをクリックすると1秒間隔で10回、ラベルの文字が変更するプログラムを考えます。

非同期処理を使わない例。
非同期処理の効用を知るために、非同期処理を使わないで処理を書いてみます。

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(1000);
                label1.Text = i.ToString();
            }
        }

実行画面

ボタンクリック後、処理が終わるまでコントロールはフリーズしたようになります。

非同期処理を使う例。
非同期処理をTaskクラスで実装してみます。

        private void button1_Click(object sender, EventArgs e)
        {
            var task = new TaskFactory().StartNew(() =>
                {
                    for (int i = 0; i < 10; i++)
                    {
                        System.Threading.Thread.Sleep(1000);
                        this.Invoke(new Action(() => label1.Text = i.ToString()));
                    }
                });
        }

実行画面

非同期処理を使うことでクリック後もコントロールの操作が可能になります。

async/awaitで非同期処理を書く例。
async/awaitを使用して非同期処理を書いてみます。

        private async void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                await Task.Run(() => System.Threading.Thread.Sleep(1000));
                label1.Text = i.ToString();
            }
        }

メソッドの定義にasyncキーワードを追加しています。これは非同期メソッドであることを宣言しています。awaitは処理本体に記述する演算子で、単純に言えば非同期で行う処理を示しています。asyncが宣言されたメソッドにはawaitの処理が必要であり(awaitがない場合はコンパイル警告が発生)、基本的にはペアで覚えれば良いと思います。
awaitが指定できる処理にはFuncもしくはActionを実行するTaskを指定します。上記のような書き方をすれば別スレッドからのUI操作にInvokeメソッドが必要ありません。これは非同期処理が別スレッドで動作した後に、再度そのメソッドの続きから始められるようにコンパイラがしてくれているそうです。

ラムダ式の場合は次のように書きます。

        private void button1_Click(object sender, EventArgs e)
        {
            Action func = async () =>
            {
                for (int i = 0; i < 10; i++)
                {
                    await Task.Run(() => System.Threading.Thread.Sleep(1000));
                    label1.Text = i.ToString();
                }
            };

            func();
        }          

まとめ。
async/awaitの書き方はLINQやラムダ式同様、一つの糖衣構文ですね。手軽に非同期処理書けまっせということでしょう。また、WindowsPhoneやタブレットなどが増えて、ユーザーがUIに触れている時間が増えたということと、開発者がこれまで作成できなかった部分というのが広がり、UIをフリーズさせないようにするために非同期処理の重要性が高まったというのが背景にあるのかも。つまり、今後、.NETが提供する時間がかかる系のAPIはasyncメソッドなので、使い方覚えてね!ということのようです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


This blog is kept spam free by WP-SpamFree.