If you want to work with Unity and threads, you'll need to implement 2 features that are unfortunately absent from Unity: A thread pool and a main thread dispatcher.

    using System;
    using System.Collections.Generic;
    using System.Threading;

    public class UnityThreadPool : UnityEngine.MonoBehaviour
    {		
		Deque<Action> mMainThreadWaitQueue;
        Deque<Action> mCurrentlyProcessing;
        static UnityThreadPool sInstance;
        Pool mPool;

        public void EnqueueOnMain(Action task) { lock (mMainThreadWaitQueue) mMainThreadWaitQueue.AddToBack(task); }
        public void EnqueueOnWorker(Action task) { mPool.QueueTask(task); }
        public static UnityThreadPool Instance {
            get {
                if (sInstance == null)
                    sInstance = new UnityEngine.GameObject("ThreadPool").AddComponent<UnityThreadPool>();
                return sInstance;
            }
        }

        void Awake()
        {
            UnityEngine.Debug.Assert(sInstance == null,"Multiple ThreadPools detected.");
            DontDestroyOnLoad(transform.gameObject);
            mPool = new Pool(UnityEngine.SystemInfo.processorCount); 
			mMainThreadWaitQueue = new Deque<Action>(10);
			mCurrentlyProcessing = new Deque<Action>(10);
        }
        void Update()
        {
			lock (mMainThreadWaitQueue) {
				if (mMainThreadWaitQueue.Count == 0)
					return;
				UnityEngine.Debug.Assert(mCurrentlyProcessing.Count == 0);
                mCurrentlyProcessing.InsertRange(0,mMainThreadWaitQueue);
                mMainThreadWaitQueue.Clear();
            }			
			var watch = System.Diagnostics.Stopwatch.StartNew(); // this is the main thread, track time so we don't block it for too long
			while (mCurrentlyProcessing.Count !=  0){
				var action = mCurrentlyProcessing.RemoveFromFront();
				try { action(); } catch (System.Exception e) { UnityEngine.Debug.LogError("Unhandled Exception in MainThread task: " + e.ToString()); }
				if (watch.ElapsedMilliseconds > 10)	{
					lock (mMainThreadWaitQueue) { mMainThreadWaitQueue.InsertRange(0,mCurrentlyProcessing);	}
					mCurrentlyProcessing.Clear();
					break;
				}
			}
        }        
        void OnDestroy() { mPool.Dispose(); }
    }

For an example implementation of `Pool` see: https://stackoverflow.com/a/436552/1612743