// This needs to be connected to a GameObject
public void RunOnMainThread(Action _method)
{
StartCoroutine(RunPostUpdate(_method));
}
IEnumerator RunPostUpdate(Action _method)
{
// If RunOnMainThread() is called in a secondary thread,
// this coroutine will start on the secondary thread
// then yield until the end of the frame on the main thread
yield return null;
_method();
}
Sorry, I wasn’t at a unity editor XP You can’t start a coroutine from a secondary thread?
I know you were hoping for something more convenient, but you could keep a list of actions guarded by a System.Threading mutex and add actions to that list in the secondary thread. Then, you can call all actions in the list and clear the list in an Update, or perhaps have a coroutine on the main thread that yields until an action is queued by another thread.
That thing you’re trying to avoid writing is exactly the thing you’re asking Unity to write. Just write it once in it’s own class and you can reuse it around in all your projects.
Not to say this will never change, but the Unity team doesn’t make tools that make multithreading easier (they only sometimes make tools that use multithreading that you don’t have access to)
Ok yeah…I found a bunch of examples on someone’s github.
It seems to be designed with very fine granularity in mind though, like modifying vertices and whatnot each frame. My intended usage was for long running operations like loading files, waiting for servers to respond, or doing heavy-duty processing in editor scripts. When those things finish, they need to run a callback on the UI thread. The coroutine solution works ok while playing, but is a no-go in editor scripts.
This is a bit out of my area of expertise, but when I took my first look at the C# job system, it seems like you can have threads wait for data to become available from other threads. For example, you could have a secondary thread modifying vertices and have the render thread wait until the new vertex data is ready.
The long-existing WWW class was designed to wait for server responses and run a callback, and I’ve seen this work in Editor scripts without halting the main thread.
I guess I’ll have to explore it when it’s out, but I didn’t find any such example in that github I linked. Also, the commands in that github code are all wrapped in a structs, which makes sense, but would be annoying to deal with for casual usage. I don’t imagine such an API designed with high-performance in mind would allow you to queue up lambda functions either, due to the allocations. Queueing lambdas to a main thread when an operation completes is fine though, if you’re dealing with the type of usage I described in my previous post.
I’m not sure what you mean. WWW has no callback mechanism. if you want to wait on it, you need to use a coroutinev, which again, doesn’t work in editor scripts. UnityWebRequest.Send() returns an AsyncOperation with a completion callback, but that still only solves a single case.
I believe this thread is dead but still. It’s realy disapointing and frustrating. I’m starting to think Unity wasn’t a best solution for my game, and i’m sorry that I didn’t choose somthing like JMonkey Engine. This is not the first issue, which makes my life a living hell with Unity. First Json serialization, then problems with simple sockets implementation, and now this one. Who could have thought that C# can be so annoying, for a Java developer.
Or you could try the new stuff. I think I saw a blog post somewhere about how to hook into Unity’s synchronization context, or create your own, or something…you’ll have to google that one.
Don’t forget to annotate your classes with [System.Serializable] or JsonUtility won’t work properly (last I checked, I use a custom JSON library).
Trying to do your own networking with raw sockets is error prone, and a LOT of work. Unity recently rewrote their networking API, and it’s much better now. If you passed on the first version, it’s definitely worth another look.