我使用了以下逻辑,当在本地运行时,它似乎是并行运行的,但当部署在Azure函数上时,它是按顺序运行的:
var allRecordTasks = new List<Task<DataRecord>>();
for (int i = 0; i < 100; i++)
{
allRecordTasks.Add(Task.Run(() => MyTask(cancellationToken)));
}
await Task.WhenAll(allRecordTasks);
我在S1计划下运行,我假设一个内核可以运行多个线程。
是否有一些设置使其工作,当运行一个具有多个核心的计划时是否可能,或者如果不使用持久的函数就不可能?
private async Task<DataRecord> MyTask(CancellationToken cancellationToken)
{
var timeSeriesType = await GetTimeSeriesTypeAsync();
var dataRecord = new DataRecord(timeSeriesType);
return dataRecord;
}
更新:仅使用
allRecordTasks.Add(MyTask(cancellationToken));
并行运行。我代码中的其他问题导致CPU内核忙碌,这并没有在本地(四核)花费太多,但影响了单核的性能。感谢Peter Bons和Stephen Cleary澄清了问题,为我指明了正确的方向。
2条答案
按热度按时间yeotifhr1#
我在S1计划下运行,我假设一个内核可以运行多个线程。
嗯,算是吧。任何内核都可以“运行”任意数量的线程。但当然,每个内核都只是一个内核,一次只能执行一条CPU指令。因此,如果您谈论的是执行CPU工作的线程,那么它一次只能执行一条。
(Most很可能,CPU实际上是周期性地在任务之间切换,但是总时间将基本上与它只是顺序地运行它们相同)。
是否有一些设置使其工作,当运行一个具有多个核心的计划时是否可能,或者如果不使用持久的函数就不可能?
它应该可以很好地与多个内核并行。
专业提示:您可以使用Process Explorer在本地运行的示例上设置Processor Affinity,以模拟一个(或两个,或...)内核。
0dxa2lsx2#
async await
是not the same thing as multithreading。它们有些相关,但将东西放在任务中绝不构成多线程。请使用
Parallel Tasks
代替,例如,请参阅与您的示例类似的the 2nd answer to this question。特别是对于Azure Functions,我不会像这样实现并行性,因为生态系统提供了通过使用queues来实现并行性的正确方法。因此,您有一个函数,它带有当前的触发器,用于检索DataRecord列表,然后将每个DataRecord放在队列中,然后是第二个函数,该函数带有处理队列中项目的QueueTrigger。只要应用服务计划允许,第二个函数就会并行执行几次。注意,我不是在说2个独立的函数应用,而是2个具有不同触发器的方法。
使用自定义多线程或并行处理还可能导致动态托管计划(Y1)出现问题,在这种情况下,函数一返回结果就可能停止执行。