2016-04-21 4 views
-1

У меня проблемы с версией UnityEngine. (Не удается обновить, игра не моя)Вызов методов из основного потока - UnityEngine C#

Сервер СЛУЧАЙНО падает, когда конкретный метод UnityEngine используется в таймер/нить (Это было исправлено в версии, я читал)

Это происходит полностью random, я получаю журнал сбоев, который начинается с таймера/потока и заканчивается методом UnityEngine. (Это никогда не происходит, когда я использую It в основной теме)

Мой вопрос: возможно ли как-то вызвать метод из основного потока, если текущий поток! = С основным потоком?

Любая помощь приветствуется

+0

Пожалуйста, добавьте свое решение в ответ, а не в качестве дополнения к вопросу. – Matt

+0

Опубликуйте свой код, возможно, вам нужно использовать сопрограммы –

+0

Не было никакой опции из-за отметки ..... – DreTaX

ответ

-2

Этот класс Loom способен вызвать определенный метод в главном потоке, это то, как вы это делаете:

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"); 
} 
Смежные вопросы