UnityEngine C# - 从主线程中调用方法 [英] Call methods from the main thread - UnityEngine C#
问题描述
我有一个UnityEngine版本的麻烦。 (无法升级,游戏是不是我的)
I'm having trouble with a UnityEngine version. (Can't upgrade, game is not mine)
当在定时器/线程是用特定的方法UnityEngine(它是固定在一个版本的服务器随机崩溃,我读了)
The server RANDOMLY crashes when a specific UnityEngine method is used in a timer/thread (It was fixed in a version, I read It)
正好完全随机的,我得到一个崩溃日志,即从定时/线程启动,并在UnityEngine方法结束。 (当我在主线程中使用它这从未发生过)
It happens totally random, I get a crash log, that starts from the timer/thread and ends at a UnityEngine method. (This never happens when I use It in the main thread)
我的问题是,是否有可能以某种方式从主线程调用该方法,如果当前线程!=与主线程?
My question is that Is It possible somehow to call the method from the main thread if the current thread != with the main thread?
任何帮助表示赞赏。
推荐答案
这织机类是能够调用从主线程的具体方法,你这是怎么做到这一点:
This Loom class is able to call the specific method from the Main thread, this is how you do It:
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");
}
这篇关于UnityEngine C# - 从主线程中调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!