在.NET Core中强制停止线程

3
假设我有一个.NET Core 2.0/2.1程序。 有一个线程正在执行以下方法。 我想强制停止它。
重要提示: 协作式多任务处理(例如,使用CancellationToken)是一件好事,但这不是本例。 XY问题(https://en.wikipedia.org/wiki/XY_problem)确实存在,但我只想知道是否可以停止此线程。
while (true)
{
    var i = 0;
    try
    {
        Console.WriteLine($"Still alive {i++}");
    }
    catch (Exception e)
    {
        Console.WriteLine($"Caught {e.GetType().Name}");
    }
}

尝试了几种选项:

关注点,从最重要到最不重要:

  • 释放锁
  • 在using指令中处理对象
  • 实际收集分配的对象

(作为一种边缘情况,我们可以假设我们的线程根本没有执行任何堆分配)


5
改变 while(true) 有什么问题?将其改为可控制的东西是否可行? - Theraot
1
仅供参考,不提供支持:https://dev59.com/NVkS5IYBdhLWcg3w-KpF#39247629。有一个“秘密”的线程中止(https://github.com/dotnet/coreclr/blob/master/tests/src/baseservices/threading/regressions/threadex.cs) - xanatos
@Theraot,可以只拿取外部程序集,在其中找到某个方法并在专用线程上执行。是的,一般来说,这是一个可怕的解决方案。但假设这个方法不是恶意的,只是可能包含导致无限循环的错误,我想在1秒钟内停止它。 - Владимир Тырин
2
如果您无法修改源代码,则考虑更改架构,以便在可以终止的隔离进程上运行此代码(必要时使用进程间通信)。编辑:如果您说可以修改源代码,但这并不简单,您可以添加if语句,在您控制的变量上进行volatile读取,并抛出异常。 - Theraot
@ВладимирТырин - 你需要知道,如果强制停止 .NET 线程,可能会损坏运行时,没有什么可以做到。你只能杀死所有线程或全部不杀死。因此,在单独的进程中执行此操作是唯一的方法。 - Enigmativity
1个回答

0
使用一个ManualResetEventSlim。该实例需要对你想要停止的线程和将导致停止的线程都可用。
在你的while(true)循环中,做如下操作:
var shouldTerminate = mres.Wait(100);
if (shouldTerminate) { break; }

这个方法会等待ManualResetEvent被设置为Set状态或者100ms,以先到达的那个为准。返回值表示事件是Set还是Unset。一开始MRE处于Unset状态,当控制线程希望终止工作线程时,它将调用Set方法,然后可以Join工作线程等待其完成。这很重要,因为在循环中,您可能正在等待网络调用完成,而工作线程实际上直到您再次回到循环顶部才会终止。如果需要,您可以在工作线程的多个点上使用Wait检查MRE,以防止继续进行昂贵的操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接