当前位置: 首页 > 编程语言 > C#

C#中的并行编程分享

时间:2023-04-10 18:11:37 C#

C#中的并行编程重新编写我的一个旧程序,称为ImageSyncer。ImageSyncer是一个非常简单的程序,它所做的只是扫描一个文件夹,找到所有以.jpg结尾的文件,然后根据它们的拍摄日期计算文件的新位置(解析xif数据,或任何它所谓的)。生成位置后,程序会检查该位置是否存在任何现有文件,如果存在,则查看要复制的文件的最后写入时间和“以自己的方式”查看文件。如果它们相等,则跳过该文件。如果不是,则创建并匹配两个文件的md5校验和。如果没有匹配项,则为要复制到的文件指定一个新位置(例如,如果要将其复制到“C:\test.jpg”,则将其复制到“C:\test(1)”.jpg“代替”。这个操作的结果被填充到一个包含两个字符串的结构类型队列中,原始文件和将它复制到的位置。然后迭代队列直到它为空并复制文件。在一个word,有4个操作:1.扫描jpegs目录2.解析xif文件并生成复制位置3.检查文件是否存在,如果需要生成新路径4.复制文件所以,我想重写这个程序,To让它并置,并能够同时做多件事,我想知道最好的方法是什么。我想出了两种我能想到的不同模型,但它们都不是做任何好事..第一个是并行化旧程序的4个步骤,这样当要执行第一步时,它是在几个线程上完成的,当整个步骤1完成后,开始步骤2。另一个(我发现它更有趣,因为我不知道该怎么做)是创建一种工作人员和消费者模型,所以当一个线程完成第1步时,另一个线程接管并执行第2步对象(或类似的东西)。不过如上所说,不知道有没有什么好的解决办法。另外,我根本不了解并行编程。我知道如何创建一个线程,以及如何让它执行一个将对象作为唯一参数的函数,我也使用过BackgroundWorker类,但我对它们都不熟悉。任何投入将不胜感激。几个选项:[但正如@JohnKnoeller指出的那样,您给出的示例可能是顺序I/O边界]这是我用于C#线程的参考:http://www.albahari.com/threading/作为单个PDF:http://www.albahari.com/threading/threading.pdf对于第二种方法:我曾研究过一些生产者/消费者多线程应用程序,其中每个任务都是某种永久循环代码。外部“初始化程序”为每个任务启动一个单独的线程,并为每个任务初始化一个EventWaitHandle。对于每个任务,都有一个全局队列可用于生成/使用输入。在您的情况下,您的外部程序会将每个目录添加到Task1的队列中,并为Task1设置EventWaitHandler。任务1将从其EventWaitHandler中“唤醒”,获取其队列中目录的计数,然后当计数大于0时,从队列中获取目录,扫描所有.jpg,并将每个.jpg位置添加到第二个队列,并为任务2设置EventWaitHandle。任务2读取其输入,处理它,将其转发到任务3的队列......让所有锁定工作可能有点痛苦(我基本上锁定了对队列的任何访问,甚至像计数这样简单的事情)。.NET4.0应该具有自动支持无锁生产者/消费者队列的数据结构。有趣的问题。我提出两种方法。第一个基于PLinq,第二个基于teRxFramework。第一个并行迭代文件。第二个异步生成目录中的文件。下面是简化版的样子(第一种方法确实需要.Net4.0,因为它使用了PLinq)关于C#学习教程,希望大家多多关注——stringdirectory="Mydirectory";varjpegFiles=System.IO.Directory.EnumerateFiles(direcory,"*.jpg");//--PLinq----------------------------------------jpegFiles.AsParallel().Select(imageFile=>new{OldLocation=imageFile,NewLocation=GenerateCopyLocation(imageFile)}).Do(fileInfo=>{if(!File.Exists(fileInfo.NewLocation)||(File.GetCreationTime(fileInfo.NewLocation))!=(File.GetCreationTime(fileInfo.NewLocation)))File.Copy(fileInfo.OldLocation,fileInfo.NewLocation);}).Run();//-------------------------------------------------//--Rx框架--------------------------------------------varresetEvent=newAutoResetEvent(false);vardoTheWork=jpegFiles.ToObservable().Select(imageFile=>new{OldLocation=imageFile,NewLocation=GenerateCopyLocation(imageFile)}).Subscribe(fileInfo=>{if(!File.Exists(文件信息.NewLocation)||(File.GetCreationTime(fileInfo.NewLocation))!=(File.GetCreationTime(fileInfo.NewLocation)))File.Copy(fileInfo.OldLocation,fileInfo.NewLocation);},()=>resetEvent.Set());重置事件.WaitOne();doTheWork.Dispose();//-------------------------------------------------本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: