添加异步并发以替换foreach循环C#
我有一个创建Zip文件的函数,当文件数只有几千个时,它工作得很好。但是,在有时间限制的操作中,这不是一个有效的解决方案。我想知道是否可以添加异步并发,以便将完成操作所需的总时间降至最低 代码:添加异步并发以替换foreach循环C#,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我有一个创建Zip文件的函数,当文件数只有几千个时,它工作得很好。但是,在有时间限制的操作中,这不是一个有效的解决方案。我想知道是否可以添加异步并发,以便将完成操作所需的总时间降至最低 代码: 我看不到任何关于线程安全的方法。因此,应该假设它们不是,并且您不能在没有坏事情发生的情况下从多个线程调用它 您可以将整个方法作为任务在后台线程上运行,这样就不会阻塞主线程,请参见和。向用户显示进度条通常也很好。但这不会使实际压缩时间更快 还有其他压缩库,我知道支持多线程压缩,但可能还有其他压缩库 此外,如
我看不到任何关于线程安全的方法。因此,应该假设它们不是,并且您不能在没有坏事情发生的情况下从多个线程调用它 您可以将整个方法作为任务在后台线程上运行,这样就不会阻塞主线程,请参见和。向用户显示进度条通常也很好。但这不会使实际压缩时间更快 还有其他压缩库,我知道支持多线程压缩,但可能还有其他压缩库 此外,如果您只想从目录创建存档,您可能需要使用
您可以在创建条目时选择压缩级别,以在速度和大小之间进行权衡。可能会提供更多的灵活性。但是这只能做这么多,压缩文件需要很多IO操作,这从根本上说是很慢的。什么类型的应用程序?为什么要先将zip存档写入内存流,然后才写入实际文件?你的意思是这样的:
Task tasks=Task.Factory.StartNew(()=>{CreateZip()})
@aniruddha这是一种方法。另一种加速过程的方法是什么?@aniruddhaTask.Factory.StartNew…
相当于Task.Run(CreateZip)
,但两者都不提供任何加速,只是UI保持响应。谢谢!这是一个控制台应用程序。我需要找到一个解决方案来加速这个过程
public static void CreateZip()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
string dirRoot = @"C:\Dir\";
//get a list of files
string[] filesToZip = Directory.GetFiles(dirRoot, "*.*",
SearchOption.AllDirectories);
string zipFileName = @"C:\Dir.zip";
using (MemoryStream zipMS = new MemoryStream())
{
using (ZipArchive zipArchive = new ZipArchive(zipMS, ZipArchiveMode.Create,
true))
{
//loop through files to add
foreach (string fileToZip in filesToZip)
{
//read the file bytes
byte[] fileToZipBytes = System.IO.File.ReadAllBytes(fileToZip);
//create the entry - this is the zipped filename
//change slashes - now it's VALID
ZipArchiveEntry zipFileEntry = zipArchive.CreateEntry(
fileToZip.Replace(dirRoot, "").Replace('\\', '/'));
//add the file contents
using (Stream zipEntryStream = zipFileEntry.Open())
using (BinaryWriter zipFileBinary = new BinaryWriter(zipEntryStream))
{
zipFileBinary.Write(fileToZipBytes);
}
}
}
using (FileStream finalZipFileStream = new FileStream(zipFileName,
FileMode.Create))
{
zipMS.Seek(0, SeekOrigin.Begin);
zipMS.CopyTo(finalZipFileStream);
}
stopwatch.Stop();
Console.WriteLine("Total time elapsed: {0}",
stopwatch.ElapsedMilliseconds / 1000);
}
}