17

How can I check if the thread I'm on is the Unity thread?

I tried capturing the threadId at constructor time, but somewhere along the lifetime of the program, the threadId moves.

In my project, some secondary thread processes need access to a newly created object.
I use the producer-consumer pattern so they can be created on the Unity thread. An object factory queues a request and on Update() the objects I requested are instantiated on the correct thread. Between Queued and Instantiated the factory method waits for an ObjectCreated event with an AutoResetEvent.

Now sometimes this factory will be called from the main thread and the AutoResetEvent will block its own thread. I also tried it the dirty way with

// First try on this thread
try
{
    return action();
}
catch (ArgumentException ex)
{
    Debug.Log("Tried on same thread, but failed. "+ex.Message);
}
PushToQueueAndWait(action);

But when unity throws the exception, caught or not, the program halts.

If I could check whether I'm on the correct thread, I could switch between queueing and just executing.

Boris Callens
  • 90,659
  • 85
  • 207
  • 305
  • I've never seen the main threadID change, how are you getting the value? `System.Threading.Thread.CurrentThread.ManagedThreadId` works for me and doesn't change insofar as my testing goes. Also, running threaded code in the Unity Editor's preview mode can result in unexpected behavior. – Jerdak Oct 21 '14 at 13:34
  • System.Threading.Thread.CurrentThread.ManagedThreadId seems to change from what it is at constructor time and what it is somewhere halfway running. Don't know any details. I have read somewhere that it could have something to do with the editor. Trying to be less vague, but haven't found a pattern yet. – Boris Callens Oct 22 '14 at 11:38
  • I'm skeptical that Unity's main thread could ever change. That would suggest it freezes the main event loop, copies that state to a new thread, and starts the loop anew. Unity doesn't support multithreading so it's hard to imagine why they would engineer such a thing. If you develop a working example of the problem it'd be great to see. – Jerdak Oct 23 '14 at 12:25
  • http://answers.unity3d.com/questions/62631/i-wonder-about-thread-id-plz-answer-me.html – Boris Callens Oct 27 '14 at 12:02

2 Answers2

27

I solved it by capturing the entire thread and then equalling it like so:

public void Start(){
    mainThread = System.Threading.Thread.CurrentThread;
}

bool isMainThread(){
    return mainThread.Equals(System.Threading.Thread.CurrentThread);
}

Related: http://answers.unity3d.com/questions/62631/i-wonder-about-thread-id-plz-answer-me.html

Tom
  • 4,910
  • 5
  • 33
  • 48
Boris Callens
  • 90,659
  • 85
  • 207
  • 305
  • 6
    Notice that `Update()` is always called on the main thread, so checking whether you're on the main thread within `Update()` will always result in `true`. I'll edit the answer to check for it in a function that can be called from any thread. – Tom Aug 10 '17 at 08:18
0

I Agree with Boris Callens but on one point, Should use mainThread.ManagedThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId when checking. Equals is defaulting to Object and is not working properly.

  • *"is not working properly"* <== could you be more specific? What's the problem with `mainThread.Equals(System.Threading.Thread.CurrentThread)`? – Theodor Zoulias Dec 05 '21 at 11:23
  • 1
    I can say, that Unity devs use exactly this way to determine main thread. You can see this in this - code https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Scripting/UnitySynchronizationContext.cs – Nikolai Feb 15 '23 at 14:23