数据流和拆分工作成小作业,然后再分组我需要做这样的工作:从数据库中为每个Page获取Page对象获取所有图像并处理它们(IO绑定,例如,上传到CDN)如果所有图像都成功完成,则在数据库中标记要处理的页面由于我需要控制并行处理多少页面,所以我决定使用TPL数据流:________________________|数据管道||缓冲块||有界容量=1||____________________________||____________________________||处理图像||转换块||有界容量=1||最大平行度=8||____________________________||____________________________||保存页面||动作块||有界容量=1||最大平行度=5||____________________________|现在我需要“处理图像”来并行处理图像,但我想在工作中限制所有并行页面中当前正在处理的图像数量。我可以将TrasnformManyBlock用于“ProcessImage”,但如何将它们返回到“SavePage”块中?____________________________||数据管道||缓冲块||有界容量=1||____________________________||_____________________________________||加载图片||变换多块||有界容量=1||最大平行度=8||______________________________________|/|___________________________________________________|______________________________________________|||过程图像|||转换块|||有界容量=1|||MaxDegreeOfParallelism=8|_||__________________________________________________||/如何按页对图像进行分组?|____________________________||保存页面||动作块||有界容量=1||最大平行度=5||____________________________||最重要的是,其中一张图片可能无法继续,我不想保存包含失败图片的页面。当给定页面的图像到达时,您可以通过记录将图像组合在一起,然后在所有图像到达时发送页面。要解决这个问题,页面需要知道它包含多少图像,但我想你知道这一点。在代码中,它看起来像这样:returnnewTransformManyBlock(split=>{varmerged=getMergedFunc(split);intcount;dictionary.TryGetValue(merged,outcount);count++;if(getSplitCount(merged)==count){dictionary.Remove(merged);返回new[]{merged};}字典[merged]=count;returnnewTMerged[0];});}使用方法:vardataPipe=newBufferBlock();varsplitter=newTransformManyBlock(page=>page.LoadImages(),newExecutionDataflowBlockOptions{MaxDegreeOfParallelism=8});varprocessImage=newTransformBlock(image=>{//在这里处理图像returnimage;},newExecutionDataflowBlockOptions{MaxDegreeOfParallelism=8});varmerger=CreaterMergerBlock((ImageWithPageimage)=>image.Page,page=>page.ImageCount);varsavePage=newActionBlock(page=>/*在此处保存页面*/,newExecutionDataflowBlockOptions{MaxDegreeOfParallelism=5});dataPipe.LinkTo(分离器);splitter.LinkTo(processImage);processImage.LinkTo(合并);merger.LinkTo(savePage);考虑将“加载图像”和“处理图像”合并为一个在TransformBlock块中,您可以毫不费力地将单个页面的图像保存在一起。要实现并发限制目标,请使用SemaphoreSlim:SemaphoreSlimprocessImageDopLimiter=newSemaphoreSlim(8);//...varpage=...;//TransformBlock块输入varimages=GetImages(page);ImageWithPage[]processedImages=images.AsParallel().Select(i=>{processImageDopLimiter.WaitOne();varresult=ProcessImage(i);processImageDopLimiter.ReleaseOne();返回结果;}).ToList();返回新的{页面,已处理的图像};这会导致相当多的线程被阻塞等待。如果您愿意,可以使用此处理的异步版本。这对这个问题并不重要。以上就是C#学习教程:数据流转和拆解工作,再分群分享全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收藏,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
