我有一个执行 HTTP POST 的 .NetCore C# 项目。该项目是在 Kubernetes 中设置的,我注意到以下日志:
Heartbeat took longer than "00:00:01" at "02/22/2020 15:43:45 +00:00".
warn: Microsoft.AspNetCore.Server.Kestrel[22]
Heartbeat took longer than "00:00:01" at "02/22/2020 15:43:46 +00:00".
warn: Microsoft.AspNetCore.Server.Kestrel[22]
Heartbeat took longer than "00:00:01" at "02/22/2020 15:43:47 +00:00".
warn: Microsoft.AspNetCore.Server.Kestrel[22]
Heartbeat took longer than "00:00:01" at "02/22/2020 15:43:48 +00:00".
warn: Microsoft.AspNetCore.Server.Kestrel[22]
Heartbeat took longer than "00:00:01" at "02/22/2020 15:43:49 +00:00".
warn: Microsoft.AspNetCore.Server.Kestrel[22]
Heartbeat took longer than "00:00:01" at "02/22/2020 15:43:50 +00:00".
warn: Microsoft.AspNetCore.Server.Kestrel[22]
Heartbeat took longer than "00:00:01" …Run Code Online (Sandbox Code Playgroud) multithreading threadpool kubernetes kestrel-http-server asp.net-core
我的同事正在使用我们没有源代码的第三方.NET库.我们正在使用ThreadPool让很多线程调用到这个库中,偶尔其中一个线程将永远挂起,而其余的线程会随意地突然出现.
所以我们想用dreaded Thread.Abort来杀死这样的线程.在我自己创建线程之前我已经完成了这个,但我从未使用过ThreadPool.如果我们跟踪每个任务的开始时间,如下所示:
static Dictionary<Thread, DateTime> started = new Dictionary<Thread, DateTime>();
static void DoSomeWork(object foo)
{
lock(started)
started[Thread.CurrentThread] = DateTime.Now;
SomeBuggyLibraryThatMightInfiniteLoopOrSomething.callSomeFunction(doo);
lock(started)
started.Remove(Thread.CurrentThread);
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以锁定并迭代正在运行的线程并调用Thread.Abort以杀死它们吗?如果我们这样做,那么我们是否需要向ThreadPool添加一个新线程来替换我们刚刚杀死的线程,或者ThreadPool会为我们处理它?
编辑:我非常清楚所有潜在的问题Thread.Abort.我知道理想情况下它应该永远不会在生产代码中使用,并且它不一定会停止线程,并且如果你在线程获得锁定时中止线程,那么你可以挂断其他线程等.但是现在我们是在时间紧,我们有体面的理由相信,在这一特定情况下,我们可以调用Thread.Abort没有把整个过程处于危险之中,我们想避免重写这个程序,以消除线程池,除非我们绝对必须.
所以我想知道的是这样的:因为我们将调用Thread.Abort上属于一个线程池线程,有没有引起这些是线程池线程的任何特殊问题,做我们必须手动旋转了一个新的线程来代替一个被杀的人还是ThreadPool会为我们做的?
如果我将作业添加到线程池中QueueUserWorkItem...如何在完成所有作业之前让我的程序继续运行?
我知道我可以添加一些逻辑来保持应用程序不运行直到所有作业都完成,但我想知道是否有类似的东西,Thread.Join()或者是否有任何方法可以检索正在分配作业的每个线程.
假设,我没有通过调用函数显式设置任何值:
System.Threading.ThreadPool.SetMaxThreads
Run Code Online (Sandbox Code Playgroud)
什么是默认值?
我ThreadPoolExecutor无法创建新线程.事实上,我写了一个有点hacky LinkedBlockingQueue,它将接受任何任务(即它是无限制的)但是调用一个额外的处理程序 - 在我的应用程序中喷出警告跟踪池后面 - 这给了我非常明确的信息,TPE拒绝创建新线程,即使队列中有数千个条目.我的构造函数如下:
private final ExecutorService s3UploadPool =
new ThreadPoolExecutor(1, 40, 1, TimeUnit.HOURS, unboundedLoggingQueue);
Run Code Online (Sandbox Code Playgroud)
为什么不创建新线程?
我在这里读到:
在v2.0,3.5和4.0中,ASP.NET 初始化每个处理器(核心)100个线程的CLR ThreadPool
这是正确的,我检查了它(我有8个核心机器,所以8*100 = 800):

maxWorkerThreads - 基于每个CPU配置进程使用的最大工作线程数.此属性的范围来自
5 through 100.默认值20.
题
我不知道数字如何适合这里:
第一段说明每个核心最多有100个线程(图像证明了它,我有8个核心).
但第二段指出每个核心的默认最大工作线程数为20.因此,如果我有8个核心,那么我必须有8*20 = 160个最大线程. 不是 800.
有人可以光明吗?
更新:
我刚刚找到了一种通过c#代码获取关键元素值的方法:

所以现在数字适合,但仍然 - MSDN说默认值是20,而不是100

然后他们确实提到了100:

这是怎么回事?
我只是想知道如何增加tomcat线程池中的线程数?以及设置最大值的数字,我不知道什么是合适的?
我在前几天读到,对于长期运行的任务,我最好的办法是手动创建线程,而不是使用.NET的线程池或任务并行.当我正在学习c#线程时,我真的希望有人能够启发我,特别是对于长时间运行的IO任务.先感谢您.
PS:我正在用一个小型数据库(5个表)构建一个小型javafx应用程序h2.
在我的所有任务中,我有一些必须连续处理(它们永远不能同时运行,必须按顺序处理).
我实现了为每组必须连续执行的任务创建一个单独线程的独立线程池.它有效,但我没有资源.我不控制组的数量,所以我最终可能会同时运行一些荒谬的线程.
有什么方法可以通过单个线程池实现这一点吗?是否有一个包含多个阻塞队列的线程池,我可以确保每个队列的串行执行?
只是强调我在第二段中所说的内容:我已经使用单线程线程池为每组必须连续执行的任务解决了这个问题.不过,我不能继续这个解决方案.有太多的团体,我不能拥有所有这些线程.
我发现了这个相关的问题,但由于它不是最近的,我仍然创造了我的.我所做的只是试图避免重新发明轮子,但似乎我没有选择.
threadpool ×10
.net ×4
c# ×4
java ×3
.net-4.0 ×1
asp.net ×1
asp.net-core ×1
c#-4.0 ×1
concurrency ×1
default ×1
h2 ×1
jdbc ×1
kubernetes ×1
tomcat7 ×1