【问题标题】:Unity C# - Is infinite loop thread terminated when class is destroyed?Unity C# - 当类被销毁时,无限循环线程是否终止?
【发布时间】:2020-05-23 22:50:46
【问题描述】:

所以我有一个游戏对象,它包含一个 A 类(扩展单一行为),它包含(创建)一个 B 类(没有单一行为)。此类 B 生成一个线程,其中包含一个 while (true) 循环,该循环执行一些工作。

我的问题是……

当这个 GameObject 被释放/销毁时,我假设其中包含的类 B 也被破坏了。当这个B类被破坏时,这个无限循环线程是否也终止了?

【问题讨论】:

  • 仅当 Dispose 取消它时。因此,您永远不应该编写无限循环。始终让它使用变量或其他方法来允许取消。
  • 所以我需要重写 dispose 并设置该变量?或者这会在析构函数(~)中工作吗?
  • 我会把它放在 Dispose 中。毕竟,这样的清理就是它的用途。但实际上编写一个合适的 Dispose 并不是那么容易。没关系不小心吞下异常的问题。你如何取消它,实际上取决于你一开始是如何开始的。有几种方法可以给特定的猫科动物剥皮。 |你有多确定,你需要一个线程?工作 CPU 是否受限?如果没有,简单的异步也可以正常工作。
  • 我像 new Thread(myfunc).Start() 一样启动了线程。这完全是一个仅受 CPU 限制的路径查找计算,不依赖于 Unity 特定对象。然而;它不是一个完全的自旋锁。即使我有一段时间(真的)..我也使用信号量来阻止大部分时间。然而;因为它没有从 MonoBehaviour 扩展,我什至可以覆盖 Dispose 吗?
  • 每个类都可以实现 IDisposeable。它是一个 .NET 甚至是 GarbageCollection 功能,而不是 Unity 或 Mono 的特殊功能。 Monobehavior 是一个 asbract 基类。而他们经常做的一件事就是“收集界面”。

标签: c# multithreading class unity3d


【解决方案1】:

已经启动的线程,主要运行到主线程结束。这是操作系统级别的回退,以避免没有拥有应用程序的僵尸线程。但是,这不是您应该依赖的后备方案。线程一旦启动就应该被视为非托管资源,因此应该有清理代码。特别是 Dispose 模式。

有这个wonderfull article on how to do it,但我觉得需要解释一下。您通常必须使用 Dispose 模式区分两种情况:

  1. 您正在直接使用未管理的资源。在这种情况下,您首先编写终结器。然后提供 Dispose 作为一种方便的方式来清理程序员的决定。
  2. 您正在处理或可能正在处理实现 IDisposeable 的东西。在这种情况下,您实现的只是 Dispose 部分,其唯一目的是将调用级联到您包裹的 Disposeable 东西。李>

95% 的类只实现 IDisposeable,因为情况 2。我们不知道是否真的有任何 Disposeable,或者这只是抽象基类的一部分。

Thread does not implement Dispose(我不知道为什么),所以你遇到了一个罕见的情况 1. Dispose 和 Finalizer 通常也被压缩为一种方法 - 通常是 Dispose 方法 - 因为它们的代码非常相似。 Finalize 和 Dispose 之间唯一真正的区别是级联行为:

  • 在完成时,您永远不会级联。最终确定在此实例和 GC 之间。
  • 在处理时,您总是级联(如果可能)。大多数情况下,它只允许级联。

我最后的建议是,由于您使用的是多线程,因此您必须注意不要吞下异常。通常,您必须编写非常糟糕的代码才能吞下异常,但对于多任务处理,您必须竭尽全力吞下任何异常。我找不到任何迹象表明 Thread 具有内置机制来持久化异常(我知道 Task 确实如此)。我能给你的只是我经常链接的两篇关于异常处理的文章:

【讨论】:

    猜你喜欢
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 2020-09-03
    • 2017-05-01
    相关资源
    最近更新 更多