每个人都知道线程应该优雅地退出,但现在我必须杀死一个线程。
当有请求提交时,我启动一个如下的线程
_thread = new Thread(ProcessTemplate);
_thread.Start();
在ProcessTemplate
方法中,它使用Google V8编译并运行从客户端发送的javascript代码。
问题是,从客户端发送的javascript可能是错误的并导致无限循环。
因此,我计算自线程启动以来的时间,如果javasctript执行时间超过10秒,我就像
一样杀死线程try
{
_thread.Abort();
}
catch
{
}
它有效,但也会影响启动_thread的当前线程。 我收到“线程被中止”。来自当前线程的异常。
如何避免/忽略异常?
答案 0 :(得分:3)
我收到"线程被中止。"来自当前线程的异常。
您在后台线程中收到此异常,而不是在以the documentation explains
启动它的主线程中:
在调用它的线程中引发ThreadAbortException 开始终止线程的过程。调用此方法 通常终止线程。
所以在这个后台线程中你可以处理这个异常:
_thread = new Thread(() =>
{
try
{
ProcessTemplate();
}
catch (ThreadAbortException ex)
{
// the thread was aborted, call ResetAbort to
// avoid rethrowing the exception
Thread.ResetAbort();
}
);
可能您看到主线程受到影响,因为在某些情况下,后台线程中未处理的异常可能会导致AppDomain失效。所以通常你应该处理这些例外。
答案 1 :(得分:0)
您可以使用Task
并将其传递给CancellationToken
答案 2 :(得分:0)
我收到"线程被中止。"来自当前线程的异常。
因为当您致电Thread.Abort
时会发生什么:
在线程上调用此方法时,系统会抛出一个 线程中的ThreadAbortException中止它。 ThreadAbortException 是一个特殊异常,可以被应用程序代码捕获,但是 除非调用ResetAbort,否则在catch块的末尾重新抛出。
您应该在后台线程中捕获ThreadAbortException
并确保其已处理。
我建议不要使用the rather dangerous abort,而是使用允许合作取消的Task Parallel Library
新功能:
var cts = new CancellationTokenSource();
var ct = cts.Token;
var javaScriptTask = await Task.Run(() => ProcessTemplate, cts.Token);
在ProcessTemplate
内,监控CancellationToken
:
ct.ThrowIfCancellationRequest();
或者,如果您在进行阻止调用时确实需要完全控制,则应该启动一个新进程来运行任务。