gpt4 book ai didi

c# - Thread.Abort() 损坏是否已本地化?

转载 作者:太空宇宙 更新时间:2023-11-03 20:40:08 25 4
gpt4 key购买 nike

我知道由于各种原因调用 Thread.Abort() 是错误的

  1. 可以锁定或在其他临界区
  2. 可能在 I/O 操作的中途,资源不会被清理
  3. 代码可以吞下 ThreadAbortException
  4. 可能处于状态更改操作的中途,并使程序处于无效状态。

假设线程的Run()方法:

  1. 不使用并发原语。
  2. 不执行任何 I/O。
  3. 不会吞下此类异常。
  4. 向只读 API 公开,因此无法更改程序状态。

问题:

如果我要在这样的线程上调用 Abort(),是否会造成局部损坏(关于损坏)?比如,我可以依靠我的程序(没有最近中止的线程)继续正常运行,还是我的整个进程/AppDomain/?然后可能已损坏?

如果我删除假设 1 和 2,abort() 损坏是否会局限于特定的并发原语和它访问的 i/o 资源?还是可以向外传播?

为什么我要鞭打 Thread.Abort() 死马:

我正在编写一个胖客户端 c# winforms 应用程序。一个功能是用户可以使用 c# 编写代码,实现我的域对象上的接口(interface),然后可以将这些接口(interface)插入我的应用程序(代码通过 codedom 编译成程序集并使用反射加载);

所以想法是用户可以写

public class CustomComputation : IComputationThing
{
public void Compute(object context)
{
while (true) ;
}
}

然后我可以反射(reflection)生成的程序集,提取并实例化 CustomComputation 的一个实例, 并调用 Compute(...);非常简单的东西。

问题是,用户然后可以编写上面的内容 - 一个无限循环,或者他决定不想等待的其他一些指数时间计算。

我正在尝试研究我的选项,以便在用户编写一些无限循环(或指数时间等)代码并希望中止时提供最大努力恢复。虽然我确实打算要求用户遵守取消模式,但最终不能保证他们会这样做。

最佳答案

正如 Vilx 所提到的,您可以考虑将“用户”代码放在另一个 AppDomain 中。

事实上,自 .Net 3.5 以来,.Net Framework 包含了 System.AddIn 命名空间,它提供了一种在单独的应用程序域(以及其他应用程序域)中隔离“加载项”代码的简化方法事物)。如果不需要太多的跨域通信,这将为您提供良好的隔离级别,最坏的情况是您拆除特定于用户代码的 AppDomain。

查看此 MSDN文章和CLR-Addin team's blog获取更多信息。

此外,虽然它不能解决所有问题,但您可以先触发 Thread.Interrupt。这将导致以与 ThreadAbortException 类似的方式引发 ThreadInterruptException,只是它只会在代码中定义的点发生;当线程阻塞或休眠时,而不是绝对在任何地方。它可能对您上面提到的紧密循环示例没有帮助,但如果循环有一个 Thread.Sleep(0) 就可以了。

你总是可以毕业你的选择:

  • 在 IComputationThing 上放置一个 Stop() 方法并要求用户实现它。
  • 如果加载项未及时响应 Stop(),请尝试 Thread.Interrupt(并记录紧循环程序可能希望在其循环中放置 Thread.Sleep(0) 以屈服于另一个线程)
  • 如果失败,请尝试 Thread.Abort,或拆除 App Domain(可能是后者直接拆除)。

关于c# - Thread.Abort() 损坏是否已本地化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3244319/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com