我有一个作业调度程序(windows服务),每隔几分钟运行一次,并试图为长时间运行的任务做异步作业。而且我确实看到在运行多个作业时CPU使用率很高。我需要避免使用任务。以不同的方式接近它?
public void Run()
{
var queueManager = new QueueManager();
foreach (var taskId in queueManager.GetTaskIdsToProcess())
{
Task.Run(async () => InvokeProcess(taskId));
}
}
private void InvokeProcess(long taskId)
{
try
{
//Long Running process code
}
catch (Exception ex)
{
//update queue failed
}
}
2条答案
按热度按时间u2nhd7ah1#
我是否需要避免使用
Task.Run
并以不同的方式处理它?Task.Run
很好。CPU峰值的原因是您分配给Task.Run
的工作是CPU受限的,至少部分是这样。使用Task.Run
本身的开销很小。你可以每秒启动一百万个Task.Run
,而CPU甚至不会注意到(假设每个Task.Run
的工作为零)。如果你想降低CPU的使用率,你基本上有两个选择:1.减少在任何给定时刻并发运行的任务的数量。
1.优化每个任务执行的工作。
两种选择都不是微不足道的。优化调度或算法的程度取决于您对任务并行库的熟悉程度和专业知识,以及。NET API和数据结构。
fykwrbwg2#
我认为这不是
Task.Run
本身,但要么InvokeProcess
是CPU密集型的,要么你的代码会导致线程池上同时调度大量的任务,而线程池又会调度多达ThreadPool.GetAvailableThreads(out var workerThreads, out var _)
个线程,因此CPU负载很高,或者两者兼而有之。通常的方法是有某种并发队列和有限数量的
Task
/Thread
处理它。例如,一个简单的可以看起来像:还可以查看: