Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在使用async/await时加速IronPdf_C#_Async Await_Parallel Processing_Ironpdf - Fatal编程技术网

C# 如何在使用async/await时加速IronPdf

C# 如何在使用async/await时加速IronPdf,c#,async-await,parallel-processing,ironpdf,C#,Async Await,Parallel Processing,Ironpdf,我试图让一段代码运行得更快。代码已在使用async/await。但还是很慢 所以我试图改变我的foreach,使用新的IAsyncEnumerable。然而,我从中获得了0的性能。它似乎是按顺序运行代码的。这让我很惊讶。我认为await foreach将在自己的线程中运行每个迭代 这是我加速代码的尝试 var bag=new ConcurrentBag();//可能不需要包 var foos=_dbContext.foos; 等待foreach(GetImagePdfs(foos)中的var f

我试图让一段代码运行得更快。代码已在使用async/await。但还是很慢


所以我试图改变我的foreach,使用新的IAsyncEnumerable。然而,我从中获得了0的性能。它似乎是按顺序运行代码的。这让我很惊讶。我认为
await foreach
将在自己的线程中运行每个迭代

这是我加速代码的尝试

var bag=new ConcurrentBag();//可能不需要包
var foos=_dbContext.foos;
等待foreach(GetImagePdfs(foos)中的var fooPdf)
{
添加(PDF);
}
专用异步IAsyncEnumerable GetImagePdfs(IEnumerable foos)
{
foreach(foos中的var foo)
{
var-imagePdf=wait-GetImagePdf(foo);
收益率回报率图像PDF;
}
}
私有异步任务GetImagePdf(Foo-Foo)
{
使用var-imageStream=wait_-httpService.downloadsync(foo.Id);
var imagePdf=await _pdfService.imagetopdasync(imageStream);
返回图像PDF;
}
使用IronPdf;
公共类PDF服务
{
//这个方法很慢
公共异步任务ImageToPdfAsync(流imageStream)
{
var imageDataURL=Util.ImageToDataUri(Image.FromStream(imageStream));
var html=$@“;
使用var renderer=new HtmlToPdf(new PdfPrintOptions()
{
PaperSize=PdfPrintOptions.PDFPPaperSize.A4,
});
返回wait renderer.renderhtmlapdfasync(html);
}
}
我还尝试了一下Parallel.ForEach

Parallel.ForEach(foos,async foo=>
{
var-imagePdf=wait-GetImagePdf(foo);
bag.Add(图片pdf);
});

然而,我一直在读,我不应该使用异步与它,所以不知道该怎么做。这样做时,IronPdf库也会崩溃。

您的
foreach
await-foreach
方法的问题是它们将按顺序执行(即使它们利用了异步和等待模式)。本质上,
await
就是这样做的,等待

关于
Parallel.ForEach
您的怀疑是正确的,它不适合异步方法和IO绑定的工作负载
Parallel.ForEach
接受一个动作委托,并将一个异步lambda赋给一个
动作
实际上只是创建了一个
异步void
,每个任务运行时都没有被观察到(这有几个缺点)

从这里可以采取很多方法,但最简单的方法是热启动每个任务,将它们投影到集合中,然后等待它们全部完成。通过这种方式,您可以将绑定IO的工作负载卸载到IO完成端口,从而允许任何潜在线程返回到线程池,以便任务调度器高效地重用,直到IO工作完成

假设没有共享资源,只需将启动的任务投影到
IEnumerable
并使用

创建一个任务,该任务将在提供的所有任务完成后完成 完成


在上面的场景中,当
Select
枚举
async
方法
GetImagePdfs
每个任务都是热启动时,任务调度器负责调度线程池中需要的任何线程。只要任何代码等待IO作业,操作系统就会进行回调,线程就会返回到池中进行重用,以此类推<代码>任务。当所有等待所有任务完成或出错时,然后返回每个结果的集合。

“它似乎按顺序运行代码”是否愿意分享得出该结论的原因?我在那里放了一些日志消息,以便打印它何时开始提取
foo.Id
以及何时将其添加到包中。顺序是:开始1,完成1,开始2,完成2,等等。当使用Parallel.ForEach?
var tasks=_dbContext.Foos.Select(x=>GetImagePdfs(x))时,您有错误消息/stacktrace;等待任务。何时(任务)作为旁注,如果我听起来很迂腐,请原谅,async/await与加快运行速度没有直接关系。如果您有许多操作要做,并且希望更快地执行,那么解决方案是并发运行,而不是异步运行。仅从同步切换到异步几乎没有任何区别。从顺序切换到并发将使世界发生巨大变化。以下是一个相关问题:
var tasks = _dbContext.Foos.Select(x => GetImagePdfs(x))
var results = await Task.WhenAll(tasks);