Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot

Novices can create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant, the one novices should use. You're probably wondering what experts are doing: They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the very same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Notice the only thing we have to do to make the above thread safe is to not edit blockor ID after calling enqueue. No volatile or explicit lock involved.

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743https://stackoverflow.com/a/436552/1612743

Novices can create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant, the one novices should use. You're probably wondering what experts are doing: They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the very same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Notice the only thing we have to do to make the above thread safe is to not edit blockor ID after calling enqueue. No volatile or explicit lock involved.

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743

Novices can create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant, the one novices should use. You're probably wondering what experts are doing: They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the very same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Notice the only thing we have to do to make the above thread safe is to not edit blockor ID after calling enqueue. No volatile or explicit lock involved.

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: https://stackoverflow.com/a/436552/1612743

deleted 123 characters in body
Source Link
Peter
  • 5.7k
  • 1
  • 26
  • 44

The primary issue with multithreaded code is that the code doesn't tell you when you screwed up. It merely crashes after running flawlessly with your changes for a couple hours. If you make a mistake, it will be expensive to find and fix it, so keep it simple.

Novices at thread safe programmingcan create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant that, the one novices should use. You're probably wondering what experts are doing.: They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the exactvery same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Notice the only thing we have to do to make the above thread safe is to not edit blockor ID after calling enqueue. No volatile or explicit lock involved.

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743

The primary issue with multithreaded code is that the code doesn't tell you when you screwed up. It merely crashes after running flawlessly with your changes for a couple hours. If you make a mistake, it will be expensive to find and fix it, so keep it simple.

Novices at thread safe programming create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant that novices should use. You're probably wondering what experts are doing. They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the exact same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743

Novices can create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant, the one novices should use. You're probably wondering what experts are doing: They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the very same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Notice the only thing we have to do to make the above thread safe is to not edit blockor ID after calling enqueue. No volatile or explicit lock involved.

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743

added 110 characters in body
Source Link
Peter
  • 5.7k
  • 1
  • 26
  • 44

The primary issue with multithreaded code is that the code doesn't tell you when you screwed up. It merely crashes after running flawlessly with your changes for a couple hours. If you make a mistake, it will be expensive to find and fix it, so keep it simple.

Novices at thread safe programming create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant that novices should use. You're probably wondering what experts are doing. They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the exact same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743

The primary issue with multithreaded code is that the code doesn't tell you when you screwed up. It merely crashes after running flawlessly with your changes for a couple hours. If you make a mistake, it will be expensive to find and fix it, so keep it simple.

Novices at thread safe programming create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

Now this is the simple and safe variant that novices should use. You're probably wondering what experts are doing. They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the exact same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743

The primary issue with multithreaded code is that the code doesn't tell you when you screwed up. It merely crashes after running flawlessly with your changes for a couple hours. If you make a mistake, it will be expensive to find and fix it, so keep it simple.

Novices at thread safe programming create thread-safe code in Unity by doing the following:

  • Copy the data they want a worker thread to work on.
  • Tell a worker thread to work on the copy.
  • From the worker thread, when the work is done, dispatch a call to the main thread to apply the changes.

This way you don't need locks and volatiles in your code, just two dispatchers (which hide all the locks and volatiles).

Now this is the simple and safe variant that novices should use. You're probably wondering what experts are doing. They do the exact same thing.

Here's some code from the Update method in one of my projects, which solves the exact same problem you're trying to solve:

Helpers.UnityThreadPool.Instance.Enqueue(() => { // This work is done by a worker thread: SimpleTexture t = Assets.Geometry.CubeSphere.CreateTexture(block, (int)Scramble(ID)); Helpers.UnityMainThreadDispatcher.Instance.Enqueue(() => { // This work is done by the Unity main thread: obj.GetComponent<MeshRenderer>().material.mainTexture = t.ToUnityTexture(); }); }); 

Here are the relevant methods from the UnityMainThreadDispatcher:

List<Action> mExecutionQueue; List<Action> mUpdateQueue; public void Update() { lock (mExecutionQueue) { mUpdateQueue.AddRange(mExecutionQueue); mExecutionQueue.Clear(); } foreach (var action in mUpdateQueue) // todo: time limit, only perform ~10ms of actions per frame { try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Exception in UnityMainThreadDispatcher: " + e.ToString()); } } mUpdateQueue.Clear(); } public void Enqueue(Action action) { lock (mExecutionQueue) mExecutionQueue.Add(action); } 

And here's a link to a thread pool implementation you can use until Unity finally supports the .NET ThreadPool: http://stackoverflow.com/a/436552/1612743

added 110 characters in body
Source Link
Peter
  • 5.7k
  • 1
  • 26
  • 44
Loading
Source Link
Peter
  • 5.7k
  • 1
  • 26
  • 44
Loading