2017-02-16 8 views
1

ユニティでは、スレッドはtransform.positionなどのようにUnityEngineが提供するオブジェクトを操作できません。このため、get_transformはメインスレッドからのみ呼び出すことができます。 しかし、これらのメソッドは、BeginReceiveのような非同期関数で使用することができます。非同期関数はスレッドまたはsth以外ではありませんか?ユニティのスレッドセーフ

私は以下のコードを試してみてください。

void Start(){ 
    AsyncCallback callback = new AsyncCallback (demo); 
    callback.BeginInvoke (null, null, null); 
} 

void demo(IAsyncResult result){ 
    Debug.Log(Thread.CurrentThread.ManagedThreadId); 
    Debug.Log(gb.transform.position.ToString()); 
} 

私はユニティ・エディタでコードを実行したときにそれが例外をスローしません。しかし、このコードをAndroidの携帯電話で直接実行すると、例外がスローされず、コードが正しく実行されました。

Line 13497: 02-20 14:37:49.973 31027 31697 I Unity : 3 
Line 13501: 02-20 14:37:49.975 31027 31697 I Unity : (0.0, 0.0, 0.0) 

だから、機能ではなく、メインスレッドの別のスレッド上で動作するようですので、誰が、なぜこのような状況に作品を変革私に言うことができる:

applogcatでログがあることを示して?

+1

"BeginReceiveのような非同期関数で" C#には多くの非同期関数があります。あなたはどちらを試しましたか?あなたは別のスレッドを使う必要がありますか? – Programmer

+0

BeginReceiveはスレッドでなければならないのですが、UnityEngineが提供するメソッドを使うことができ、例外もありません。 – deadmarston

+0

BeginReceiveどこから?どのクラス?さまざまなC#API /クラスの多くがあります。 – Programmer

答えて

2

Unityは、メインスレッド以外のスレッドからほとんどのAPI関数を呼び出すことはできません。すべてのイベント/メッセージ処理は実際にはメインスレッド上で行われます。

IEnumeratorに基づくコルーチンシステムは、ハックのビットであり、実際にはマルチスレッドを可能にしません(.NET 4.5非同期/待機機能であっても必ずしもマルチスレッド実行を意味するわけではありません)。

UnityEngine APIを呼び出すと、メインスレッドになります。

+0

私は関数 'Debug.Log(Thread.CurrentThread.ManagedThreadId)'を呼び出して、両方の関数のスレッドIDをチェックしようとしています。私は上記のデモコードを与える、あなたはなぜ私に教えてくれますか? – deadmarston

+0

私はWindows上でしかコードをテストできませんでした。これは、異なるスレッドIDとエラーの予想される結果を提供します。 – apk

+0

私はこれを自分のAndroid端末で実行し、上記のログを添付します。 – deadmarston

1

UI APIはUIとは別のスレッドから呼び出すことはできません。

これは、Unityが舞台裏でどのように働いているかを簡単にし、実際には速くします。

一部の非同期メソッドは、イベントループを使用して送出され、別のスレッドでは送出されません。メソッドが非同期であるという理由だけで、別のスレッドで実行されるわけではありません。

Unityの最も明白な例はCoroutinesです。それらは非同期で実行されますが、メインスレッドで実行されます。これは、Unityがすべてをリストに追加し、すべてのフレームで実行するので可能です。