SlideShare ist ein Scribd-Unternehmen logo
1 von 68
Downloaden Sie, um offline zu lesen
さては非同期だなオメー!
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!
ご静聴ありがとうございました

Weitere ähnliche Inhalte

Was ist angesagt?

Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Yoshifumi Kawai
 
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~UnityTechnologiesJapan002
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術Unity Technologies Japan K.K.
 
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現Yoshifumi Kawai
 
MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~torisoup
 
UniTask入門
UniTask入門UniTask入門
UniTask入門torisoup
 
UniRx完全に理解した
UniRx完全に理解したUniRx完全に理解した
UniRx完全に理解したtorisoup
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
 
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜Unity Technologies Japan K.K.
 
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
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門torisoup
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介torisoup
 
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!Unity Technologies Japan K.K.
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理torisoup
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはJun-ichi Sakamoto
 
新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編infinite_loop
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All ThingsUnityTechnologiesJapan002
 
インタフェース完全に理解した
インタフェース完全に理解したインタフェース完全に理解した
インタフェース完全に理解したtorisoup
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計Yoshinori Matsunobu
 

Was ist angesagt? (20)

Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
【Unite Tokyo 2019】Unityだったら簡単!マルチプレイ用ゲームサーバ開発 ~実践編~
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
【Unity道場スペシャル 2017京都】最適化をする前に覚えておきたい技術
 
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
Unityによるリアルタイム通信とMagicOnionによるC#大統一理論の実現
 
MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~MagicOnion~C#でゲームサーバを開発しよう~
MagicOnion~C#でゲームサーバを開発しよう~
 
UniTask入門
UniTask入門UniTask入門
UniTask入門
 
UniRx完全に理解した
UniRx完全に理解したUniRx完全に理解した
UniRx完全に理解した
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
【Unity道場】AssetGraph入門 〜ノードを駆使しててUnityの面倒な手作業を自動化する方法〜
 
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]
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
 
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
【CEDEC2017】Unityを使ったNintendo Switch™向けのタイトル開発・移植テクニック!!
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
 
新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編新入社員のための大規模ゲーム開発入門 サーバサイド編
新入社員のための大規模ゲーム開発入門 サーバサイド編
 
【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things【Unite Tokyo 2019】Understanding C# Struct All Things
【Unite Tokyo 2019】Understanding C# Struct All Things
 
インタフェース完全に理解した
インタフェース完全に理解したインタフェース完全に理解した
インタフェース完全に理解した
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 

Ähnlich wie 【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
 

Ähnlich wie 【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
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 

Mehr von 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.
 
Cinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作るCinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作る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.
 

Mehr von 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のハッシュ計算を高速に行う話
 
Cinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作るCinemachineで見下ろし視点のカメラを作る
Cinemachineで見下ろし視点のカメラを作る
 
徹底解説 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ティーチャートレーニングデイ -認定アソシエイト編-
 

Kürzlich hochgeladen

CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 

Kürzlich hochgeladen (8)

CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 

【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のプロファイラーから見えないので注意