据我所知,由于各种原因调用Thread.Abort()是错误的和错误的
假设线程的Run()方法:
问题:
如果我在这样的线程上调用Abort(),那么损坏(关于腐败)是否已经本地化?在,我可以依赖我的程序,没有最近中止的线程,继续正常行为,或者是我的整个进程/ AppDomain / ??然后可能被腐蚀了?
如果我删除假设1和2会中止()腐败被本地化为特定的并发原语和它访问的I / O资源?或者它可以向外传播吗?
为什么我鞭打Thread.Abort()死马:
我正在编写一个胖客户端c#winforms应用程序。一个功能是用户能够在c#中编写代码,在我的域对象上实现接口,然后可以将其插入我的应用程序(代码通过codedom编译成程序集并使用反射加载);
所以想法是用户可以写
public class CustomComputation : IComputationThing
{
public void Compute(object context)
{
while (true) ;
}
}
然后我可以反思生成的程序集,提取并实例化CustomComputation
的实例,并调用Compute(...);
非常简单的东西。
问题是用户可以写上面的 - 无限循环,或者他决定不想等待的其他指数时间计算。
我正在尝试调查我的选择,以便在用户编写一些无限循环(或指数时间等)代码并希望从中止时提供尽力恢复。虽然我打算要求用户遵守取消模式但最终无法保证他们会这样做。
答案 0 :(得分:1)
除非您了解.NET运行时库的每个细节,否则我怀疑您实际上可以保证您的假设(特别是4和1)。违反假设4真正需要的是一个单独的静态变量......
如果您使用生成的代码,则单独的AppDomain更容易停止和卸载,与线程不同,这可以作为托管进程的正常生命周期的一部分来完成。
答案 1 :(得分:1)
Thread.Abort()肯定会污染你的AppDomain,但我相信它也会破坏整个进程的稳定性。我找不到这么快的链接。
因此,您必须在单独的(一次性)流程中运行它。
答案 2 :(得分:1)
由于用户代码是如此动态(我希望典型的开发人员在编写代码时会进行数十次测试运行),所以无论如何都要将它放在一个单独的AppDomain中,这样你就可以卸载它。如果是这样,那么腐败只会影响单独的appdomain,无论如何都会很快卸载。
现在,我实际上开始想知道如果用户代码会产生另一个线程/ appdomain会发生什么,但这是另一个问题。也许它可以通过一些权限来解决,我对它们并不熟悉。
答案 3 :(得分:1)
看看.net Terrarium项目。这是一个点对点演示应用程序,用于演示.net框架的对等功能和黑客安全性。开发人员可以匿名编写和上传AI代码来控制虚拟玻璃容器中的昆虫,该虚拟玻璃容器作为数千台机器上的对等生态系统运行。
他们使用反射来确保上传的代码是安全的:您无法执行IO,限制锁定以及静态变量。它们也限制了你被允许“思考”的时间。这个应用程序的优点应该足够好。
答案 4 :(得分:1)
如Vilx所述 - 您可以考虑将“用户”代码放在另一个AppDomain中。
事实上,自.Net 3.5以来,.Net Framework已经包含了System.AddIn
命名空间,它提供了一种在单独的应用程序域(以及其他内容)中隔离“加载项”代码的简化方法。如果不需要太多的跨域通信,这将为您提供良好的隔离级别,最糟糕的情况是您拆除特定于用户代码的AppDomain。
有关详细信息,请参阅此MSDN文章和CLR-Addin team's blog。
此外,尽管它没有解决所有问题,但您可以从触发Thread.Interrupt开始。这将导致以与ThreadAbortException类似的方式引发ThreadInterruptException,除了它将在代码中的定义点处发生;当线程阻塞或睡眠时,而不是绝对任何地方。它可能无助于你上面提到的紧密循环示例,但如果循环有一个Thread.Sleep(0)。
您可以随时选择自己的选择: