はかせのラボ

私の頭の中を書いていく雑記ブログです

Unity C# async/await 値を返す

あいさつ

どうも、はかせです。
今回は前回の予告通りasync/awaitを使った値返しをやりたいと思います。

実装方法

大体説明は前回終えているのでさっそくコードです。

public class AsyncAwaitTest : MonoBehaviour
{
    private SynchronizationContext context;
    // Use this for initialization
    async void Start()
    {
        context = SynchronizationContext.Current;
        ThirdAsync().FireForget();
        await FirstAsync();
        await SecondAsync();
    }

    private async Task FirstAsync()
    {
        Debug.Log("FirstAsync Start!");
        //1秒待つ
        await Task.Delay(1000);
        Debug.Log("FirstAsync Done!");
    }

    private async Task SecondAsync()
    {
        Debug.Log("SecondAsync Start!");
        Debug.Log("Please press spacekey");
        //スペースキーの入力待ち 
        var isInput = false;
        await Task.Run(() => 
        {
            while (!isInput)
            {
                context.Post(__ => isInput = Input.GetKeyDown(KeyCode.Space), null);
            }
        } );
        Debug.Log("SecondAsync Done!");
    }

    private async Task ThirdAsync()
    {
        Debug.Log("ThirdAsync Start!");
        var test = await HeveyTaskAsync();
        Debug.Log(test);
        Debug.Log("ThirdAsync Done!");
    }
    //適当に思い処理
    private async Task<int> HeveyTaskAsync()
    {
        var rnd = 100000;
        var result = 0;
        await Task.Run(() =>
        {
            for(int i = 0;i < (rnd * rnd); i++) { result++; }
        });
        return result;
    } 

}

後半の2つが新しく追加したやつです。
Task<int>ってのが新しいやつですね。
今までは処理の終了のみを報告していたのですが、
Task<int>は処理の終了とint型の値を報告してくれます。
(<>が全角なのはそうしないとタグと認識されて記事上に出ないからです)

処理としては、まず重い処理を走らせて
そのあと今までの非同期メソッドを動かしています。

それでは実行結果です。
重い処理だとわかるよういつもより長めです。
f:id:hakase0274:20181208234205g:plain

あとがき

今回はasync/awaitを用いた値返しでした。
コルーチンで値を返したりしたい場合、
メンバ変数を使うかコールバックを使わないとできません。

コードの総量は大きく変わりませんが、こっちのほうがやってることが
直感的にわかりやすいと思っています。

今回は短めですがこれで終わりたいと思います。
(いつもこれくらいで終わりたい)

それでは今回はこの辺でノシ