2016-04-21 73 views
-1

我遇到了UnityEngine版本的问题。 (无法升级,游戏是不是我的)来自主线程的调用方法 - UnityEngine C#

当定时器/线程是用特定的方法UnityEngine(它是固定在一个版本,我读它)服务器随机崩溃

它发生完全随机,我得到一个崩溃日志,从计时器/线程开始,并在UnityEngine方法结束。 (当我在主线程中使用它时,这种情况绝不会发生)

我的问题是,如果当前线程!=与主线程调用方法从主线程调用是否可能?

任何帮助表示赞赏

+0

请加上您的解决方案作为一个答案,而不是作为该问题的增编。 – Matt

+0

发布你的代码,可能你需要使用协程 –

+0

由于该标记没有选项..... – DreTaX

回答

-2

这织机类是能够调用从主线程的具体方法,你这是怎么做到这一点:

public class Loom : MonoBehaviour 
{ 
    public static int maxThreads = 10; 
    static int numThreads; 

    private static Loom _current; 
    private int _count; 
    public static Loom Current 
    { 
     get 
     { 
      Initialize(); 
      return _current; 
     } 
    } 

    public void Awake() 
    { 
     _current = this; 
     initialized = true; 
    } 

    static bool initialized; 

    static void Initialize() 
    { 
     if (!initialized) 
     { 

      if (!Application.isPlaying) 
       return; 
      initialized = true; 
      var g = new GameObject("Loom"); 
      _current = g.AddComponent<Loom>(); 
     } 

    } 

    private List<Action> _actions = new List<Action>(); 
    public struct DelayedQueueItem 
    { 
     public float time; 
     public Action action; 
    } 
    private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>(); 

    List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>(); 

    public static void QueueOnMainThread(Action action) 
    { 
     QueueOnMainThread(action, 0f); 
    } 
    public static void QueueOnMainThread(Action action, float time) 
    { 
     if (time != 0) 
     { 
      lock (Current._delayed) 
      { 
       Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action }); 
      } 
     } 
     else 
     { 
      lock (Current._actions) 
      { 
       Current._actions.Add(action); 
      } 
     } 
    } 

    public static Thread RunAsync(Action a) 
    { 
     Initialize(); 
     while (numThreads >= maxThreads) 
     { 
      Thread.Sleep(1); 
     } 
     Interlocked.Increment(ref numThreads); 
     ThreadPool.QueueUserWorkItem(RunAction, a); 
     return null; 
    } 

    private static void RunAction(object action) 
    { 
     try 
     { 
      ((Action)action)(); 
     } 
     catch 
     { 
     } 
     finally 
     { 
      Interlocked.Decrement(ref numThreads); 
     } 

    } 


    public void OnDisable() 
    { 
     if (_current == this) 
     { 

      _current = null; 
     } 
    } 



    // Use this for initialization 
    public void Start() 
    { 

    } 

    List<Action> _currentActions = new List<Action>(); 

    // Update is called once per frame 
    public void Update() 
    { 
     lock (_actions) 
     { 
      _currentActions.Clear(); 
      _currentActions.AddRange(_actions); 
      _actions.Clear(); 
     } 
     foreach (var a in _currentActions) 
     { 
      a(); 
     } 
     lock (_delayed) 
     { 
      _currentDelayed.Clear(); 
      _currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time)); 
      foreach (var item in _currentDelayed) 
       _delayed.Remove(item); 
     } 
     foreach (var delayed in _currentDelayed) 
     { 
      delayed.action(); 
     } 
    } 
} 



//Usage 
public void Call() 
{ 
    if (Thread.CurrentThread.ManagedThreadId != TestClass.MainThread.ManagedThreadId) 
    { 
     Loom.QueueOnMainThread(() => { 
      Call(); 
     }); 
     return; 
    } 
    Console.WriteLine("Hello"); 
}