Unityで並行処理
マルチスレッド化した無限ループを準備してネットワーク処理をブンブン回したいのですが、調べるとやり方がいろいろあるようで難しいです。
その基本を理解するために、実験として最小限のプログラムを作ってみました。
参考記事
初心者のためのTask.Run(), async/awaitの使い方
つかうもの
task.Run(() => {[処理]})
というコマンドを使います。
このコマンドは、[処理]の部分を別スレッドで実行するものらしいです。
Unityのバージョンは2020.3.25f1のもので試しました。
理解のための素朴なコード
もろもろ省略したシンプルなコードです。
Unityで以下のスクリプトを作成し、空のオブジェクトなどにアタッチすれば実行可能です。が、トラブル防止のための処理なども省略してしまっているので、実行はちょっと危険です。ご注意ください。
(実行してみた場合にはPCの再起動をお勧めします。)
using UnityEngine;
using System.Threading.Tasks;
public class LoopSample : MonoBehaviour
{
//スタート時に1回だけ以下を実行
void Start()
{
Thread_1();//無限ループ実行用の関数を起動
}
//無限ループ実行用の関数
public void Thread_1()
{
Task.Run(() =>//このコマンドで以下を別スレッドで実行
{
while (true)//無限ループの本体
{
Debug.Log("Test");//コンソールにTestを表示
}
});
}
}
実行結果
実行するとUnityのConsoleにTestという文字が表示され、Collapseがオンになっていれば、表示数が右端にどんどんカウントアップされていきます。
そしてなんと停止ボタンを押してもカウントアップが続きます。別スレッドとはいえ、なんかすごいです。自分の環境ではUnityがそのままフリーズしてしまいました。
少しだけ事故防止処理を施したコード
今度は以下の2つの処理を入れてもうちょっとだけ扱いやすくしてみます。
・停止した時に無限ループスレッドも止まるようにする。
・例外が発生した時にエラーログが出るようにする。
using UnityEngine;
using System.Threading.Tasks;
public class LoopSample2 : MonoBehaviour
{
private bool Flag_loop = true;//無限ループ制御用フラグを設定し、揚げる
void Start()
{
Thread_1();
}
void OnApplicationQuit()//アプリ終了時の処理(無限ループを解放)
{
Flag_loop = false;//無限ループフラグを下げる
}
public void Thread_1()//無限ループ本体
{
Task.Run(() =>
{
while (Flag_loop)//無限ループフラグをチェック
{
try
{
Debug.Log("Test");
}
catch (System.Exception e)//例外をチェック
{
Debug.LogWarning(e);//エラーを表示
}
}
});
}
}
実行結果
実行するとUnityのConsoleにTestという文字が表示され、Collapseがオンになっていれば、表示数が右端にどんどんカウントアップされていきます。
...というところは先ほどと同じですが、今回は停止ボタンでカウントの表示も止まるハズです。
さいごに
素朴に並行処理を試してみるだけの記事がなかったのでまとめてみました。
実際に動かすことで、苦手意識から開放されそうな気がします。
より本格的な並行処理、非同期処理を実現するためには、async/awaitのコマンドや、UniTaskやジョブシステムといった仕組みが用意されています。
下記のような参考になる記事がたくさんありますので、ここから先はネクストステップに進みやすいかと思います。
Taskを極めろ!async/await完全攻略
また、間違いがありましたらご指摘いただければ幸いです。