SlideShare a Scribd company logo
1 of 68
Download to read offline
さては非同期だなオメー!
async/await完全に理解しよう
ユニティ・テクノロジーズ・ジャパン
名雪 通
2018/05/07 - 09
名雪 通
asyncのほう。
エンジニア
安原 祐二
awaitのほう。
エンジニア
#unitetokyo2018
#完全に理解した
2018年5月
Unity 2018.1 リリース
.NET 4.xがExperimental→Stableに!
C# 4.0→6.0
参考: C# 5.0の新機能
• async/await
• 呼び出し元情報属性
参考: C# 6.0の新機能
• 読み取り専用の自動プロパティ
• 自動プロパティの初期化子
• 式形式の関数メンバー
• using static
• null条件演算子
• 文字列補間
• 例外フィルター
• nameof式
• catchブロックとfinallyブロックでのawait
• インデックス初期化子
• コレクション初期化子の拡張メソッド
• オーバーロード解決の改善
async/await
async/awaitとは何か
async(= asynchronous = 非同期)
awaitを使うメソッドにつける必要があるキーワード
await(= 待つ)
非同期(async)メソッドを呼び出し、
その完了まで実行を中断するキーワード
ここまででのasync/await理解率: 10%
ここで問題です
このコードの開始→終了まで何秒かかるでしょうか
static void AsyncTest() {
// 開始
Console.WriteLine(DateTime.Now);
Thread.Sleep(5000);
// 終了
Console.WriteLine(DateTime.Now);
}
普通に5秒
次の問題
このコードは開始→終了まで何秒かかるでしょうか
static void AsyncTest() {
// 開始
Console.WriteLine(DateTime.Now);
AsyncMethod();
// 終了
Console.WriteLine(DateTime.Now);
}
static async void AsyncMethod() {
Thread.Sleep(5000);
}
やっぱり5秒
別にasyncをつけただけで非同期になるわけではない
次はawaitの問題
このコードは開始→終了まで何秒かかるでしょうか
static void AsyncTest() {
// 開始
Console.WriteLine(DateTime.Now);
Task.Delay(5000);
// 終了
Console.WriteLine(DateTime.Now);
}
なんと0秒
次の問題
このコードは開始→終了まで何秒かかるでしょうか
static async void AsyncTest() {
// 開始
Console.WriteLine(DateTime.Now);
await Task.Delay(5000);
// 終了
Console.WriteLine(DateTime.Now);
}
5秒になった!
async/awaitは
「処理を非同期に行うための仕組み」ではなく、
「非同期の処理を待つための仕組み」である
理解率: 50%
では、どのように
その「非同期の処理を待つための仕組み」を
実現しているのか?
逆コンパイルしてみよう
さっきのコード
static async void AsyncTest() {
// 開始
Console.WriteLine(DateTime.Now);
await Task.Delay(5000);
// 終了
Console.WriteLine(DateTime.Now);
}
逆コンパイルした結果
    private static void AsyncTest() {
        <AsyncTest>d__1 <AsyncTest>d__ = new <AsyncTest>d__1();
        <AsyncTest>d__.<>t__builder = AsyncVoidMethodBuilder.Create();
        <AsyncTest>d__.<>1__state = -1;
        AsyncVoidMethodBuilder <>t__builder = <AsyncTest>d__.<>t__builder;
        <>t__builder.Start(ref <AsyncTest>d__);
    }
インナークラスも生成されている
    private sealed class <AsyncTest>d__1 : IAsyncStateMachine {
        public int <>1__state;
        public AsyncVoidMethodBuilder <>t__builder;
        private TaskAwaiter <>u__1;
        private void MoveNext() {
            int num = <>1__state;
            try {
                TaskAwaiter awaiter;
                if (num != 0) {
                    Console.WriteLine(DateTime.Now);
                    awaiter = Task.Delay(5000).GetAwaiter();
                    if (!awaiter.get_IsCompleted()) {
                        num = (<>1__state = 0);
                        <>u__1 = awaiter;
                        <AsyncTest>d__1 <AsyncTest>d__ = this;
                        <>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter,
<AsyncTest>d__1>(ref awaiter, ref <AsyncTest>d__);
                        return;
                    }
                } else {
                    awaiter = <>u__1;
                    <>u__1 = default(TaskAwaiter);
                    num = (<>1__state = -1);
                }
                awaiter.GetResult();
                Console.WriteLine(DateTime.Now);
            }
            catch (Exception exception)
            {
                <>1__state = -2;
                <>t__builder.SetException(exception);
                return;
            }
            <>1__state = -2;
            <>t__builder.SetResult();
        }
    }
わかりやすく書き直してみる
元の関数
    private static void AsyncTest() {
        var stateMachine = new AsyncTestStateMachine();
        stateMachine.builder = AsyncVoidMethodBuilder.Create();
        stateMachine.state = -1;
        stateMachine.builder.Start(ref stateMachine);
    }
static async void AsyncTest() {
Console.WriteLine(DateTime.Now); // 開始
await Task.Delay(5000);
Console.WriteLine(DateTime.Now); // 終了
}
    private sealed struct AsyncTestStateMachine : IAsyncStateMachine {
        public int state;
        public AsyncVoidMethodBuilder builder;
        private TaskAwaiter taskAwaiter;
        private void MoveNext() {
            int num = state;
            try {
                TaskAwaiter awaiter;
                if (num != 0) {
                    Console.WriteLine(DateTime.Now);
                    awaiter = Task.Delay(5000).GetAwaiter();
                    if (!awaiter.IsCompleted) {
                        num = state = 0;
                        taskAwaiter = awaiter;
                        AsyncTestStateMachine stateMachine = this;
                        builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref
awaiter, ref stateMachine);
                        return;
                    }
                } else {
                    awaiter = taskAwaiter;
                    taskAwaiter = default(TaskAwaiter);
                    num = state = -1;
                }
                awaiter.GetResult();
                Console.WriteLine(DateTime.Now);
            }
            catch (Exception exception)
            {
                state = -2;
                builder.SetException(exception);
                return;
            }
            state = -2;
            builder.SetResult();
        }
    }
インナークラス
    private sealed struct AsyncTestStateMachine : IAsyncStateMachine {
        public int state;
        public AsyncVoidMethodBuilder builder;
        private TaskAwaiter taskAwaiter;
        private void MoveNext() {
            int num = state;
            try {
                TaskAwaiter awaiter;
                if (num != 0) {
                    Console.WriteLine(DateTime.Now);
                    awaiter = Task.Delay(5000).GetAwaiter();
                    if (!awaiter.IsCompleted) {
                        num = state = 0;
                        taskAwaiter = awaiter;
                        AsyncTestStateMachine stateMachine = this;
                        builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref
awaiter, ref stateMachine);
                        return;
                    }
                } else {
                    awaiter = taskAwaiter;
                    taskAwaiter = default(TaskAwaiter);
                    num = state = -1;
                }
                awaiter.GetResult();
                Console.WriteLine(DateTime.Now);
            }
            catch (Exception exception)
            {
                state = -2;
                builder.SetException(exception);
                return;
            }
            state = -2;
            builder.SetResult();
        }
    }
インナークラスのMoveNext
private void MoveNext() {
    private sealed struct AsyncTestStateMachine : IAsyncStateMachine {
        public int state;
        public AsyncVoidMethodBuilder builder;
        private TaskAwaiter taskAwaiter;
        private void MoveNext() {
            int num = state;
            try {
                TaskAwaiter awaiter;
                if (num != 0) {
                    Console.WriteLine(DateTime.Now);
                    awaiter = Task.Delay(5000).GetAwaiter();
                    if (!awaiter.IsCompleted) {
                        num = state = 0;
                        taskAwaiter = awaiter;
                        AsyncTestStateMachine stateMachine = this;
                        builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref
awaiter, ref stateMachine);
                        return;
                    }
                } else {
                    awaiter = taskAwaiter;
                    taskAwaiter = default(TaskAwaiter);
                    num = state = -1;
                }
                awaiter.GetResult();
                Console.WriteLine(DateTime.Now);
            }
            catch (Exception exception)
            {
                state = -2;
                builder.SetException(exception);
                return;
            }
            state = -2;
            builder.SetResult();
        }
    }
インナークラス
TaskAwaiter awaiter;
if (num != 0) {
    Console.WriteLine(DateTime.Now);
    awaiter = Task.Delay(5000).GetAwaiter();
Console.WriteLine(DateTime.Now);
関数を抜けてる!
    private sealed struct AsyncTestStateMachine : IAsyncStateMachine {
        public int state;
        public AsyncVoidMethodBuilder builder;
        private TaskAwaiter taskAwaiter;
        private void MoveNext() {
            int num = state;
            try {
                TaskAwaiter awaiter;
                if (num != 0) {
                    Console.WriteLine(DateTime.Now);
                    awaiter = Task.Delay(5000).GetAwaiter();
                    if (!awaiter.IsCompleted) {
                        num = state = 0;
                        taskAwaiter = awaiter;
                        AsyncTestStateMachine stateMachine = this;
                        builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref
awaiter, ref stateMachine);
                        return;
                    }
                } else {
                    awaiter = taskAwaiter;
                    taskAwaiter = default(TaskAwaiter);
                    num = state = -1;
                }
                awaiter.GetResult();
                Console.WriteLine(DateTime.Now);
            }
            catch (Exception exception)
            {
                state = -2;
                builder.SetException(exception);
                return;
            }
            state = -2;
            builder.SetResult();
        }
    }
 return;
問題です
Task.Delayの前後の実行スレッドは?
static void Main(string[] args) {
AsyncTest();
Console.ReadLine();
}
static async void AsyncTest() {
// 前
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
await Task.Delay(5000);
// 後
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
違う
同じコードをUnityで実行すると?
    async void Start () {
        // 前
        Debug.Log(Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(5000);
        // 後
        Debug.Log(Thread.CurrentThread.ManagedThreadId);
    }
同じ!
SynchronizationContextが
await後のコードを実行するスレッドを決める
CLIアプリケーションには
SynchronizationContextが存在しないため
自動的にスレッドプール上で実行される
UnityにはUnityの
SynchronizationContextの実装がある
参考: https://github.com/Unity-Technologies/UnityCsReference/blob/
83cceb769a97e24025616acc7503e9c21891f0f1/Runtime/Export/
UnitySynchronizationContext.cs
もともとUnityには
非同期処理のための仕組みがあります
コルーチン
• C# 2.0の反復子(yield)を利用した継続処理の仕組み
• 様々なタイミングを待つことができる(Unity側の仕組みによる)
• フレームの終わり
• FixedUpdate
• 指定した秒数後(の最初のフレーム)
• その他非同期処理(AsyncOperation)
• 戻り値を返しにくい
コルーチンの例
    IEnumerator Coroutine() {
        // 前
        Debug.Log(Thread.CurrentThread.ManagedThreadId);
        yield return new WaitForSeconds(0.5f);
        // 後
        Debug.Log(Thread.CurrentThread.ManagedThreadId);
    }
逆コンパイルしてみよう
    private IEnumerator Coroutine() {
        return new <Coroutine>c__Iterator1();
    }
    private sealed class <Coroutine>c__Iterator1 : IEnumerator, IDisposable, IEnumerator<object> {
        internal object $current;
        internal bool $disposing;
        internal int $PC;
        object IEnumerator<object>.Current {
            [DebuggerHidden]
            get
            {
                return $current;
            }
        }
        object IEnumerator.Current {
            [DebuggerHidden]
            get
            {
                return $current;
            }
        }
        public <Coroutine>c__Iterator1() {
        }
        public bool MoveNext() {
            //IL_003c: Unknown result type (might be due to invalid IL or missing references)
            //IL_0041: Expected O, but got Unknown
            uint num = (uint)$PC;
            $PC = -1;
            switch (num) {
            case 0u:
                Debug.Log((object)Thread.CurrentThread.ManagedThreadId);
                $current = (object)new WaitForSeconds(0.5f);
                if (!$disposing) {
                    $PC = 1;
                }
                return true;
            case 1u:
                Debug.Log((object)Thread.CurrentThread.ManagedThreadId);
                $PC = -1;
                break;
            }
            return false;
        }
        public void Dispose() {
            $disposing = true;
            $PC = -1;
        }
        public void Reset() {
            throw new NotSupportedException();
        }
    }
C# Job System
• 2018.1の新機能
• クラスが使えない
• Burstコンパイラーによる最適化の恩恵を受けられる
• 処理はUnityのワーカースレッドで実行される
awaitできるのはTaskだけではない
TaskをawaitするのがTaskAwaiter
Awaiterを作ればTaskでなくてもawaitできる  
awaitしたいクラスにGetAwaiter拡張メソッドを実装する
public static class AsyncOperationAwaitable {
    public static Awaiter GetAwaiter(this AsyncOperation asyncOperation) {
        return new Awaiter(asyncOperation);
    }
    public class AsyncOperationAwaiter : INotifyCompletion {
    private AsyncOperation asyncOperation;
     private System.Action continuation;
    public AsyncOperationAwaiter(AsyncOperation asyncOperation) {
    this.asyncOperation = asyncOperation;
     CoroutineDispatcher.Get().DispatchCoroutine(WrappedCoroutine());
    }
    public bool IsCompleted {
    get { return asyncOperation.isDone; }
    }
    public void OnCompleted(System.Action continuation) {
    this.continuation = continuation;
    }
     public void GetResult() {
     }
    public IEnumerator WrappedCoroutine() {
    yield return asyncOperation;
     continuation();
    }
    }
}
• サンプルです。そのまま使わないでください。
サンプル: HTTPリクエストして
レスポンスのJSONをパースする
コルーチンで書く
    IEnumerator Coroutine() {
        UnityWebRequest request = UnityWebRequest.Get("https://api.etherscan.io/api?
module=proxy&action=eth_getBlockByNumber&tag=0x517df3&boolean=true&apikey=YourApiKeyToken");
        yield return request.SendWebRequest();
        var text = request.downloadHandler.text;
        var data = (JObject)JsonConvert.DeserializeObject(text);
        var result = (JObject)data["result"];
        var transactions = (JArray)result["transactions"];
        Debug.Log(transactions.Count);
    }
非同期
同期
Task + async/awaitを使って書く
    async Task Async() {
        UnityWebRequest request = UnityWebRequest.Get("https://api.etherscan.io/api?
module=proxy&action=eth_getBlockByNumber&tag=0x517df3&boolean=true&apikey=YourApiKeyToken");
        await request.SendWebRequest();
        var text = request.downloadHandler.text;
        await Task.Run(() => {
            var data = (JObject)JsonConvert.DeserializeObject(text);
            var result = (JObject)data["result"];
            var transactions = (JArray)result["transactions"];
            Debug.Log(JsonConvert.DeserializeObject(text));
        });
    }
非同期
非同期
JSONパース処理(45ms)分が
非同期(メインスレッド外)で行われるように
実はUnityのプロファイラーには
Profiler.BeginThreadProfilingしたスレッドしか
表示されない
スレッドプールのスレッドごとに
Profiler.BeginThreadProfilingを呼ぶ
TaskSchedulerを作ればよい
参考: https://github.com/tnayuki/Unity-AsyncAwait/blob/master/Assets/
UnityTaskScheduler.cs
※ 参照実装です。そのまま使わないでください。
まとめ
• async/awaitは非同期処理を待つための仕組み
• 仕組みがわからない時は逆コンパイルしよう(ライセンスには気をつけよう)
• コルーチン/C# Job Systemと使い分けよう
• Task.Runに回した処理は通常はUnityのプロファイラーから見えないので注意
「async/await完全に理解した」
Thank you!
ご静聴ありがとうございました

More Related Content

What's hot

【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~UnityTechnologiesJapan002
 
MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~torisoup
 
Unityネイティブプラグインマニアクス #denatechcon
Unityネイティブプラグインマニアクス #denatechconUnityネイティブプラグインマニアクス #denatechcon
Unityネイティブプラグインマニアクス #denatechconDeNA
 
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]DeNA
 
Cinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作るCinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作るUnity Technologies Japan K.K.
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方Yoshifumi Kawai
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作るtorisoup
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話torisoup
 
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例sairoutine
 
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~UnityTechnologiesJapan002
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?Yoshitaka Kawashima
 
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~UnityTechnologiesJapan002
 
The Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnionThe Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnionYoshifumi Kawai
 
アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~gree_tech
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理torisoup
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けモノビット エンジン
 
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術Unity Technologies Japan K.K.
 
A Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in DepthA Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in DepthYoshifumi Kawai
 
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!Unity Technologies Japan K.K.
 

What's hot (20)

【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
【Unite Tokyo 2019】今すぐ現場で覚えておきたい最適化技法 ~「ゲシュタルト・オーディン」開発における最適化事例~
 
MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~
 
Unityネイティブプラグインマニアクス #denatechcon
Unityネイティブプラグインマニアクス #denatechconUnityネイティブプラグインマニアクス #denatechcon
Unityネイティブプラグインマニアクス #denatechcon
 
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
Unity 2018-2019を見据えたDeNAのUnity開発のこれから [DeNA TechCon 2019]
 
Cinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作るCinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作る
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話
 
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
CEDEC2019 大規模モバイルゲーム運用におけるマスタデータ管理事例
 
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
 
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
【Unite Tokyo 2019】大量のアセットも怖くない!~HTTP/2による高速な通信の実装例~
 
The Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnionThe Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnion
 
アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~アプリ起動時間高速化 ~推測するな、計測せよ~
アプリ起動時間高速化 ~推測するな、計測せよ~
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
【CEDEC2018】一歩先のUnityでのパフォーマンス/メモリ計測、デバッグ術
 
A Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in DepthA Brief History of UniRx/UniTask, IUniTaskSource in Depth
A Brief History of UniRx/UniTask, IUniTaskSource in Depth
 
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
 
Riderはいいぞ!
Riderはいいぞ!Riderはいいぞ!
Riderはいいぞ!
 

Similar to 【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう

NoSQL and JavaScript 2013-02-09
NoSQL and JavaScript 2013-02-09NoSQL and JavaScript 2013-02-09
NoSQL and JavaScript 2013-02-09WakandaJA
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライMasanobu Sato
 
ゼロから始めたE2Eテスト
ゼロから始めたE2Eテストゼロから始めたE2Eテスト
ゼロから始めたE2Eテストushiboy
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~normalian
 
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)Tusyoshi Matsuzaki
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDEdcubeio
 
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」de:code 2017
 
Swift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposiumSwift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposiumTomohiro Kumagai
 
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallなおき きしだ
 
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題Makoto Setoh
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめYu Nobuoka
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...Shotaro Suzuki
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8y_taka_23
 
The Next Generation for C# Developers
The Next Generation for C# DevelopersThe Next Generation for C# Developers
The Next Generation for C# DevelopersTakayoshi Tanaka
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用Yatabe Terumasa
 

Similar to 【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう (20)

NoSQL and JavaScript 2013-02-09
NoSQL and JavaScript 2013-02-09NoSQL and JavaScript 2013-02-09
NoSQL and JavaScript 2013-02-09
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライ
 
ゼロから始めたE2Eテスト
ゼロから始めたE2Eテストゼロから始めたE2Eテスト
ゼロから始めたE2Eテスト
 
T93 com入門
T93 com入門T93 com入門
T93 com入門
 
20141129-dotNet2015
20141129-dotNet201520141129-dotNet2015
20141129-dotNet2015
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE).NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
.NET Web プログラミングにおける非同期 IO のすべて (Build Insider OFFLINE)
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
 
Swift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposiumSwift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposium
 
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fallこれからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
 
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
The Next Generation for C# Developers
The Next Generation for C# DevelopersThe Next Generation for C# Developers
The Next Generation for C# Developers
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 

More from Unity Technologies Japan K.K.

建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】
建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】
建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】Unity Technologies Japan K.K.
 
UnityのクラッシュをBacktraceでデバッグしよう!
UnityのクラッシュをBacktraceでデバッグしよう!UnityのクラッシュをBacktraceでデバッグしよう!
UnityのクラッシュをBacktraceでデバッグしよう!Unity Technologies Japan K.K.
 
Unityで始めるバーチャルプロダクション
Unityで始めるバーチャルプロダクションUnityで始めるバーチャルプロダクション
Unityで始めるバーチャルプロダクションUnity Technologies Japan K.K.
 
ビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしよう
ビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしようビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしよう
ビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしようUnity Technologies Japan K.K.
 
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーションビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - UnityステーションUnity Technologies Japan K.K.
 
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそうビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそうUnity Technologies Japan K.K.
 
PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!
PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!
PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!Unity Technologies Japan K.K.
 
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】Unity Technologies Japan K.K.
 
Unity教える先生方注目!ティーチャートレーニングデイを体験しよう
Unity教える先生方注目!ティーチャートレーニングデイを体験しようUnity教える先生方注目!ティーチャートレーニングデイを体験しよう
Unity教える先生方注目!ティーチャートレーニングデイを体験しようUnity Technologies Japan K.K.
 
「原神」におけるコンソールプラットフォーム開発
「原神」におけるコンソールプラットフォーム開発「原神」におけるコンソールプラットフォーム開発
「原神」におけるコンソールプラットフォーム開発Unity Technologies Japan K.K.
 
FANTASIANの明日使えない特殊テクニック教えます
FANTASIANの明日使えない特殊テクニック教えますFANTASIANの明日使えない特殊テクニック教えます
FANTASIANの明日使えない特殊テクニック教えますUnity Technologies Japan K.K.
 
インディーゲーム開発の現状と未来 2021
インディーゲーム開発の現状と未来 2021インディーゲーム開発の現状と未来 2021
インディーゲーム開発の現状と未来 2021Unity Technologies Japan K.K.
 
建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】
建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】
建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】Unity Technologies Japan K.K.
 
Burstを使ってSHA-256のハッシュ計算を高速に行う話
Burstを使ってSHA-256のハッシュ計算を高速に行う話Burstを使ってSHA-256のハッシュ計算を高速に行う話
Burstを使ってSHA-256のハッシュ計算を高速に行う話Unity Technologies Japan K.K.
 
Unityティーチャートレーニングデイ -認定プログラマー編-
Unityティーチャートレーニングデイ -認定プログラマー編-Unityティーチャートレーニングデイ -認定プログラマー編-
Unityティーチャートレーニングデイ -認定プログラマー編-Unity Technologies Japan K.K.
 
Unityティーチャートレーニングデイ -認定3Dアーティスト編-
Unityティーチャートレーニングデイ -認定3Dアーティスト編-Unityティーチャートレーニングデイ -認定3Dアーティスト編-
Unityティーチャートレーニングデイ -認定3Dアーティスト編-Unity Technologies Japan K.K.
 
Unityティーチャートレーニングデイ -認定アソシエイト編-
Unityティーチャートレーニングデイ -認定アソシエイト編-Unityティーチャートレーニングデイ -認定アソシエイト編-
Unityティーチャートレーニングデイ -認定アソシエイト編-Unity Technologies Japan K.K.
 
今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識
今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識 今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識
今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識 Unity Technologies Japan K.K.
 

More from Unity Technologies Japan K.K. (20)

建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】
建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】
建築革命、更に更に進化!便利さ向上【Unity Reflect ver 3.0 】
 
UnityのクラッシュをBacktraceでデバッグしよう!
UnityのクラッシュをBacktraceでデバッグしよう!UnityのクラッシュをBacktraceでデバッグしよう!
UnityのクラッシュをBacktraceでデバッグしよう!
 
Unityで始めるバーチャルプロダクション
Unityで始めるバーチャルプロダクションUnityで始めるバーチャルプロダクション
Unityで始めるバーチャルプロダクション
 
ビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしよう
ビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしようビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしよう
ビジュアルスクリプティング (旧:Bolt) で始めるUnity入門3日目 ゲームをカスタマイズしよう
 
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーションビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
ビジュアルスクリプティングで始めるUnity入門2日目 ゴールとスコアの仕組み - Unityステーション
 
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそうビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
ビジュアルスクリプティングで始めるUnity入門1日目 プレイヤーを動かそう
 
PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!
PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!
PlasticSCMの活用テクニックをハンズオンで一緒に学ぼう!
 
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
 
Unity教える先生方注目!ティーチャートレーニングデイを体験しよう
Unity教える先生方注目!ティーチャートレーニングデイを体験しようUnity教える先生方注目!ティーチャートレーニングデイを体験しよう
Unity教える先生方注目!ティーチャートレーニングデイを体験しよう
 
「原神」におけるコンソールプラットフォーム開発
「原神」におけるコンソールプラットフォーム開発「原神」におけるコンソールプラットフォーム開発
「原神」におけるコンソールプラットフォーム開発
 
FANTASIANの明日使えない特殊テクニック教えます
FANTASIANの明日使えない特殊テクニック教えますFANTASIANの明日使えない特殊テクニック教えます
FANTASIANの明日使えない特殊テクニック教えます
 
インディーゲーム開発の現状と未来 2021
インディーゲーム開発の現状と未来 2021インディーゲーム開発の現状と未来 2021
インディーゲーム開発の現状と未来 2021
 
建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】
建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】
建築革命、更に進化!デジタルツイン基盤の真打ち登場【概要編 Unity Reflect ver 2.1 】
 
Burstを使ってSHA-256のハッシュ計算を高速に行う話
Burstを使ってSHA-256のハッシュ計算を高速に行う話Burstを使ってSHA-256のハッシュ計算を高速に行う話
Burstを使ってSHA-256のハッシュ計算を高速に行う話
 
徹底解説 Unity Reflect【開発編 ver2.0】
徹底解説 Unity Reflect【開発編 ver2.0】徹底解説 Unity Reflect【開発編 ver2.0】
徹底解説 Unity Reflect【開発編 ver2.0】
 
徹底解説 Unity Reflect【概要編 ver2.0】
徹底解説 Unity Reflect【概要編 ver2.0】徹底解説 Unity Reflect【概要編 ver2.0】
徹底解説 Unity Reflect【概要編 ver2.0】
 
Unityティーチャートレーニングデイ -認定プログラマー編-
Unityティーチャートレーニングデイ -認定プログラマー編-Unityティーチャートレーニングデイ -認定プログラマー編-
Unityティーチャートレーニングデイ -認定プログラマー編-
 
Unityティーチャートレーニングデイ -認定3Dアーティスト編-
Unityティーチャートレーニングデイ -認定3Dアーティスト編-Unityティーチャートレーニングデイ -認定3Dアーティスト編-
Unityティーチャートレーニングデイ -認定3Dアーティスト編-
 
Unityティーチャートレーニングデイ -認定アソシエイト編-
Unityティーチャートレーニングデイ -認定アソシエイト編-Unityティーチャートレーニングデイ -認定アソシエイト編-
Unityティーチャートレーニングデイ -認定アソシエイト編-
 
今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識
今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識 今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識
今だから聞きたい!Unity2017/18ユーザーのためのUnity2019 LTS基礎知識
 

Recently uploaded

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (7)

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 

【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう

  • 9. 参考: C# 5.0の新機能 • async/await • 呼び出し元情報属性
  • 10. 参考: C# 6.0の新機能 • 読み取り専用の自動プロパティ • 自動プロパティの初期化子 • 式形式の関数メンバー • using static • null条件演算子 • 文字列補間 • 例外フィルター • nameof式 • catchブロックとfinallyブロックでのawait • インデックス初期化子 • コレクション初期化子の拡張メソッド • オーバーロード解決の改善
  • 13. async(= asynchronous = 非同期) awaitを使うメソッドにつける必要があるキーワード
  • 17. このコードの開始→終了まで何秒かかるでしょうか static void AsyncTest() { // 開始 Console.WriteLine(DateTime.Now); Thread.Sleep(5000); // 終了 Console.WriteLine(DateTime.Now); }
  • 18.
  • 21. このコードは開始→終了まで何秒かかるでしょうか static void AsyncTest() { // 開始 Console.WriteLine(DateTime.Now); AsyncMethod(); // 終了 Console.WriteLine(DateTime.Now); } static async void AsyncMethod() { Thread.Sleep(5000); }
  • 25. このコードは開始→終了まで何秒かかるでしょうか static void AsyncTest() { // 開始 Console.WriteLine(DateTime.Now); Task.Delay(5000); // 終了 Console.WriteLine(DateTime.Now); }
  • 26.
  • 29. このコードは開始→終了まで何秒かかるでしょうか static async void AsyncTest() { // 開始 Console.WriteLine(DateTime.Now); await Task.Delay(5000); // 終了 Console.WriteLine(DateTime.Now); }
  • 34. さっきのコード static async void AsyncTest() { // 開始 Console.WriteLine(DateTime.Now); await Task.Delay(5000); // 終了 Console.WriteLine(DateTime.Now); }
  • 35. 逆コンパイルした結果     private static void AsyncTest() {         <AsyncTest>d__1 <AsyncTest>d__ = new <AsyncTest>d__1();         <AsyncTest>d__.<>t__builder = AsyncVoidMethodBuilder.Create();         <AsyncTest>d__.<>1__state = -1;         AsyncVoidMethodBuilder <>t__builder = <AsyncTest>d__.<>t__builder;         <>t__builder.Start(ref <AsyncTest>d__);     }
  • 36. インナークラスも生成されている     private sealed class <AsyncTest>d__1 : IAsyncStateMachine {         public int <>1__state;         public AsyncVoidMethodBuilder <>t__builder;         private TaskAwaiter <>u__1;         private void MoveNext() {             int num = <>1__state;             try {                 TaskAwaiter awaiter;                 if (num != 0) {                     Console.WriteLine(DateTime.Now);                     awaiter = Task.Delay(5000).GetAwaiter();                     if (!awaiter.get_IsCompleted()) {                         num = (<>1__state = 0);                         <>u__1 = awaiter;                         <AsyncTest>d__1 <AsyncTest>d__ = this;                         <>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, <AsyncTest>d__1>(ref awaiter, ref <AsyncTest>d__);                         return;                     }                 } else {                     awaiter = <>u__1;                     <>u__1 = default(TaskAwaiter);                     num = (<>1__state = -1);                 }                 awaiter.GetResult();                 Console.WriteLine(DateTime.Now);             }             catch (Exception exception)             {                 <>1__state = -2;                 <>t__builder.SetException(exception);                 return;             }             <>1__state = -2;             <>t__builder.SetResult();         }     }
  • 38. 元の関数     private static void AsyncTest() {         var stateMachine = new AsyncTestStateMachine();         stateMachine.builder = AsyncVoidMethodBuilder.Create();         stateMachine.state = -1;         stateMachine.builder.Start(ref stateMachine);     } static async void AsyncTest() { Console.WriteLine(DateTime.Now); // 開始 await Task.Delay(5000); Console.WriteLine(DateTime.Now); // 終了 }
  • 39.     private sealed struct AsyncTestStateMachine : IAsyncStateMachine {         public int state;         public AsyncVoidMethodBuilder builder;         private TaskAwaiter taskAwaiter;         private void MoveNext() {             int num = state;             try {                 TaskAwaiter awaiter;                 if (num != 0) {                     Console.WriteLine(DateTime.Now);                     awaiter = Task.Delay(5000).GetAwaiter();                     if (!awaiter.IsCompleted) {                         num = state = 0;                         taskAwaiter = awaiter;                         AsyncTestStateMachine stateMachine = this;                         builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref awaiter, ref stateMachine);                         return;                     }                 } else {                     awaiter = taskAwaiter;                     taskAwaiter = default(TaskAwaiter);                     num = state = -1;                 }                 awaiter.GetResult();                 Console.WriteLine(DateTime.Now);             }             catch (Exception exception)             {                 state = -2;                 builder.SetException(exception);                 return;             }             state = -2;             builder.SetResult();         }     } インナークラス
  • 40.     private sealed struct AsyncTestStateMachine : IAsyncStateMachine {         public int state;         public AsyncVoidMethodBuilder builder;         private TaskAwaiter taskAwaiter;         private void MoveNext() {             int num = state;             try {                 TaskAwaiter awaiter;                 if (num != 0) {                     Console.WriteLine(DateTime.Now);                     awaiter = Task.Delay(5000).GetAwaiter();                     if (!awaiter.IsCompleted) {                         num = state = 0;                         taskAwaiter = awaiter;                         AsyncTestStateMachine stateMachine = this;                         builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref awaiter, ref stateMachine);                         return;                     }                 } else {                     awaiter = taskAwaiter;                     taskAwaiter = default(TaskAwaiter);                     num = state = -1;                 }                 awaiter.GetResult();                 Console.WriteLine(DateTime.Now);             }             catch (Exception exception)             {                 state = -2;                 builder.SetException(exception);                 return;             }             state = -2;             builder.SetResult();         }     } インナークラスのMoveNext private void MoveNext() {
  • 41.     private sealed struct AsyncTestStateMachine : IAsyncStateMachine {         public int state;         public AsyncVoidMethodBuilder builder;         private TaskAwaiter taskAwaiter;         private void MoveNext() {             int num = state;             try {                 TaskAwaiter awaiter;                 if (num != 0) {                     Console.WriteLine(DateTime.Now);                     awaiter = Task.Delay(5000).GetAwaiter();                     if (!awaiter.IsCompleted) {                         num = state = 0;                         taskAwaiter = awaiter;                         AsyncTestStateMachine stateMachine = this;                         builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref awaiter, ref stateMachine);                         return;                     }                 } else {                     awaiter = taskAwaiter;                     taskAwaiter = default(TaskAwaiter);                     num = state = -1;                 }                 awaiter.GetResult();                 Console.WriteLine(DateTime.Now);             }             catch (Exception exception)             {                 state = -2;                 builder.SetException(exception);                 return;             }             state = -2;             builder.SetResult();         }     } インナークラス TaskAwaiter awaiter; if (num != 0) {     Console.WriteLine(DateTime.Now);     awaiter = Task.Delay(5000).GetAwaiter(); Console.WriteLine(DateTime.Now);
  • 42. 関数を抜けてる!     private sealed struct AsyncTestStateMachine : IAsyncStateMachine {         public int state;         public AsyncVoidMethodBuilder builder;         private TaskAwaiter taskAwaiter;         private void MoveNext() {             int num = state;             try {                 TaskAwaiter awaiter;                 if (num != 0) {                     Console.WriteLine(DateTime.Now);                     awaiter = Task.Delay(5000).GetAwaiter();                     if (!awaiter.IsCompleted) {                         num = state = 0;                         taskAwaiter = awaiter;                         AsyncTestStateMachine stateMachine = this;                         builder.AwaitUnsafeOnCompleted<TaskAwaiter, AsyncTestStateMachine>(ref awaiter, ref stateMachine);                         return;                     }                 } else {                     awaiter = taskAwaiter;                     taskAwaiter = default(TaskAwaiter);                     num = state = -1;                 }                 awaiter.GetResult();                 Console.WriteLine(DateTime.Now);             }             catch (Exception exception)             {                 state = -2;                 builder.SetException(exception);                 return;             }             state = -2;             builder.SetResult();         }     }  return;
  • 44. Task.Delayの前後の実行スレッドは? static void Main(string[] args) { AsyncTest(); Console.ReadLine(); } static async void AsyncTest() { // 前 Console.WriteLine(Thread.CurrentThread.ManagedThreadId); await Task.Delay(5000); // 後 Console.WriteLine(Thread.CurrentThread.ManagedThreadId); }
  • 46. 同じコードをUnityで実行すると?     async void Start () {         // 前         Debug.Log(Thread.CurrentThread.ManagedThreadId);         await Task.Delay(5000);         // 後         Debug.Log(Thread.CurrentThread.ManagedThreadId);     }
  • 51. コルーチン • C# 2.0の反復子(yield)を利用した継続処理の仕組み • 様々なタイミングを待つことができる(Unity側の仕組みによる) • フレームの終わり • FixedUpdate • 指定した秒数後(の最初のフレーム) • その他非同期処理(AsyncOperation) • 戻り値を返しにくい
  • 52. コルーチンの例     IEnumerator Coroutine() {         // 前         Debug.Log(Thread.CurrentThread.ManagedThreadId);         yield return new WaitForSeconds(0.5f);         // 後         Debug.Log(Thread.CurrentThread.ManagedThreadId);     }
  • 53. 逆コンパイルしてみよう     private IEnumerator Coroutine() {         return new <Coroutine>c__Iterator1();     }     private sealed class <Coroutine>c__Iterator1 : IEnumerator, IDisposable, IEnumerator<object> {         internal object $current;         internal bool $disposing;         internal int $PC;         object IEnumerator<object>.Current {             [DebuggerHidden]             get             {                 return $current;             }         }         object IEnumerator.Current {             [DebuggerHidden]             get             {                 return $current;             }         }         public <Coroutine>c__Iterator1() {         }         public bool MoveNext() {             //IL_003c: Unknown result type (might be due to invalid IL or missing references)             //IL_0041: Expected O, but got Unknown             uint num = (uint)$PC;             $PC = -1;             switch (num) {             case 0u:                 Debug.Log((object)Thread.CurrentThread.ManagedThreadId);                 $current = (object)new WaitForSeconds(0.5f);                 if (!$disposing) {                     $PC = 1;                 }                 return true;             case 1u:                 Debug.Log((object)Thread.CurrentThread.ManagedThreadId);                 $PC = -1;                 break;             }             return false;         }         public void Dispose() {             $disposing = true;             $PC = -1;         }         public void Reset() {             throw new NotSupportedException();         }     }
  • 54. C# Job System • 2018.1の新機能 • クラスが使えない • Burstコンパイラーによる最適化の恩恵を受けられる • 処理はUnityのワーカースレッドで実行される
  • 57. awaitしたいクラスにGetAwaiter拡張メソッドを実装する public static class AsyncOperationAwaitable {     public static Awaiter GetAwaiter(this AsyncOperation asyncOperation) {         return new Awaiter(asyncOperation);     }     public class AsyncOperationAwaiter : INotifyCompletion {     private AsyncOperation asyncOperation;      private System.Action continuation;     public AsyncOperationAwaiter(AsyncOperation asyncOperation) {     this.asyncOperation = asyncOperation;      CoroutineDispatcher.Get().DispatchCoroutine(WrappedCoroutine());     }     public bool IsCompleted {     get { return asyncOperation.isDone; }     }     public void OnCompleted(System.Action continuation) {     this.continuation = continuation;     }      public void GetResult() {      }     public IEnumerator WrappedCoroutine() {     yield return asyncOperation;      continuation();     }     } } • サンプルです。そのまま使わないでください。
  • 59. コルーチンで書く     IEnumerator Coroutine() {         UnityWebRequest request = UnityWebRequest.Get("https://api.etherscan.io/api? module=proxy&action=eth_getBlockByNumber&tag=0x517df3&boolean=true&apikey=YourApiKeyToken");         yield return request.SendWebRequest();         var text = request.downloadHandler.text;         var data = (JObject)JsonConvert.DeserializeObject(text);         var result = (JObject)data["result"];         var transactions = (JArray)result["transactions"];         Debug.Log(transactions.Count);     } 非同期 同期
  • 60.
  • 61. Task + async/awaitを使って書く     async Task Async() {         UnityWebRequest request = UnityWebRequest.Get("https://api.etherscan.io/api? module=proxy&action=eth_getBlockByNumber&tag=0x517df3&boolean=true&apikey=YourApiKeyToken");         await request.SendWebRequest();         var text = request.downloadHandler.text;         await Task.Run(() => {             var data = (JObject)JsonConvert.DeserializeObject(text);             var result = (JObject)data["result"];             var transactions = (JArray)result["transactions"];             Debug.Log(JsonConvert.DeserializeObject(text));         });     } 非同期 非同期
  • 62.
  • 66. まとめ • async/awaitは非同期処理を待つための仕組み • 仕組みがわからない時は逆コンパイルしよう(ライセンスには気をつけよう) • コルーチン/C# Job Systemと使い分けよう • Task.Runに回した処理は通常はUnityのプロファイラーから見えないので注意