是否可以在 Unity 编辑器中选择性地阻止某些程序集的重新加载?
Is it possible to block reload of some assemblies selectively in Unity Editor?
运行 遇到线程和 Unity 的一些问题,其中如果线程在后台 运行,并且编辑器调用重新加载,比如您最终或立即编辑脚本, Unity 会崩溃或死机。
问题是因为所有程序集都被重新加载,因此线程 assembly/dll 有一个悬空指针。
为了使问题进一步复杂化,即使线程真正完成了它的主例程,例如在 运行 外部可执行文件的情况下,关闭该可执行文件,或退出并返回退出代码,线程仍未正确清理,仍然会导致崩溃。中止、取消甚至加入主线程也不起作用。还有
一旦 Unity 重新加载它的所有程序集,就会发生一些奇怪的事情。日志文件总是显示 Unity 成功完成重新加载,但紧接着,我们有悬空指针。
我知道您可以使用
阻止重新加载
EditorApplication.LockReloadAssemblies();
,甚至您可以使用回调预重载来拦截重载...但是如果有一种方法可以阻止重新加载所有特定程序集,那将解决崩溃问题。
更简单的是一个文件夹,比如 Plugins,其中的任何程序集都不会重新编译。
这个问题与运行时/播放模式无关,而只是在编辑器内部,因为我正在开发生产工具和插件。
有人知道解决这个令人沮丧的问题的方法吗?
这是不可能的。我采用的包含 IronPython 内存泄漏的解决方案是将脚本引擎放入它自己的应用程序域中,从而有效地包含内存泄漏。如果您决定操纵编辑器,这是可能的,但如果您将它放在一个线程上,您将 运行 陷入麻烦而不试图将它分派到主线程。这包括 Debug.Log。
我在 Unity Editor 中使用 Thread 做一些后台工作时也遇到了这个问题。我能够通过使用 UnityEditor.Callbacks.DidReloadScripts
中止并重新启动线程来解决挂起问题。这是我测试的代码:
using System.Threading;
using UnityEngine;
public static class Manager1
{
public static int Counter = 0;
private static Thread Thread;
static Manager1()
{
ThreadStart();
}
[UnityEditor.Callbacks.DidReloadScripts]
static void DidReload()
{
Restart();
}
static void Task()
{
while (true)
{
Counter++;
Thread.Sleep(100);
}
}
static void Abort()
{
Debug.Log("ABORT");
Thread.Abort();
Thread = null;
}
static void Restart()
{
Abort();
ThreadStart();
}
static void ThreadStart()
{
Thread = new Thread(Task);
Thread.Start();
}
}
但是,请注意,我 还 必须在线程中添加对 Thread.Sleep
的调用。我无法找到有关此的任何信息,但我观察到如果没有那个调用,线程中永远不会引发 ThreadAbortException
并且线程当然永远不会结束。
运行 遇到线程和 Unity 的一些问题,其中如果线程在后台 运行,并且编辑器调用重新加载,比如您最终或立即编辑脚本, Unity 会崩溃或死机。
问题是因为所有程序集都被重新加载,因此线程 assembly/dll 有一个悬空指针。
为了使问题进一步复杂化,即使线程真正完成了它的主例程,例如在 运行 外部可执行文件的情况下,关闭该可执行文件,或退出并返回退出代码,线程仍未正确清理,仍然会导致崩溃。中止、取消甚至加入主线程也不起作用。还有 一旦 Unity 重新加载它的所有程序集,就会发生一些奇怪的事情。日志文件总是显示 Unity 成功完成重新加载,但紧接着,我们有悬空指针。
我知道您可以使用
阻止重新加载EditorApplication.LockReloadAssemblies();
,甚至您可以使用回调预重载来拦截重载...但是如果有一种方法可以阻止重新加载所有特定程序集,那将解决崩溃问题。
更简单的是一个文件夹,比如 Plugins,其中的任何程序集都不会重新编译。
这个问题与运行时/播放模式无关,而只是在编辑器内部,因为我正在开发生产工具和插件。
有人知道解决这个令人沮丧的问题的方法吗?
这是不可能的。我采用的包含 IronPython 内存泄漏的解决方案是将脚本引擎放入它自己的应用程序域中,从而有效地包含内存泄漏。如果您决定操纵编辑器,这是可能的,但如果您将它放在一个线程上,您将 运行 陷入麻烦而不试图将它分派到主线程。这包括 Debug.Log。
我在 Unity Editor 中使用 Thread 做一些后台工作时也遇到了这个问题。我能够通过使用 UnityEditor.Callbacks.DidReloadScripts
中止并重新启动线程来解决挂起问题。这是我测试的代码:
using System.Threading;
using UnityEngine;
public static class Manager1
{
public static int Counter = 0;
private static Thread Thread;
static Manager1()
{
ThreadStart();
}
[UnityEditor.Callbacks.DidReloadScripts]
static void DidReload()
{
Restart();
}
static void Task()
{
while (true)
{
Counter++;
Thread.Sleep(100);
}
}
static void Abort()
{
Debug.Log("ABORT");
Thread.Abort();
Thread = null;
}
static void Restart()
{
Abort();
ThreadStart();
}
static void ThreadStart()
{
Thread = new Thread(Task);
Thread.Start();
}
}
但是,请注意,我 还 必须在线程中添加对 Thread.Sleep
的调用。我无法找到有关此的任何信息,但我观察到如果没有那个调用,线程中永远不会引发 ThreadAbortException
并且线程当然永远不会结束。