C
C#2y ago
EdgarKa

How to save time on multiple file zipping

Hiya. I have a tool that builds and copies files into specified directory and then zips them. It is currently consists of the following: Class { Foreach () { F1 (); // copying files Zip(); // zipping these files F2(); F3(); Zip(); // zipping F1, F2 & F3 into different archive }} I would like to call Zips and while they are zipping, perform further until it hits another Zip function and start when previous zipping is finished. I’ve tried to play around with async (currently learning), but not exactly sure how to work it out. Could anyone advice please?
12 Replies
Pobiega
Pobiega2y ago
async is the answer. from your outline, its a bit unclear what the foreach above is? the core idea of async is that you get an object called a "Task" back that represents the execution of your method you can check the status on it and most importantly, await it. Awaiting a task means "wait until that task finishes" so for example, you could start zipping three different things and when they are all done, zip those 3 zips
// start all three zipping operations
var zip1 = Zip("file1");
var zip2 = Zip("file2");
var zip3 = Zip("file3");

// wait for all of them to finish
var results = await Task.WhenAll(zip1, zip2, zip3);
// at this point, we know all three are complete

foreach (var result in results)
{
// do something, idk.
}
// start all three zipping operations
var zip1 = Zip("file1");
var zip2 = Zip("file2");
var zip3 = Zip("file3");

// wait for all of them to finish
var results = await Task.WhenAll(zip1, zip2, zip3);
// at this point, we know all three are complete

foreach (var result in results)
{
// do something, idk.
}
public static async Task<ZipResult> Zip(string path)
public static async Task<ZipResult> Zip(string path)
EdgarKa
EdgarKa2y ago
Thank you for your response @Pobiega! Foreach is loops through folders to grab stuff from It does sound like I'd need to restructure the zipping
Pobiega
Pobiega2y ago
So, what is the stuff you would like to do asynchronously? The zipping of the folders?
Becquerel
Becquerel2y ago
Note that there isn't an immediately-obvious API for asynchronous file copying (due to limitations in the Win32 API iirc). I think you have to go through the FileStream class
using (FileStream SourceStream = File.Open(sourceFilePath, FileMode.Open))
{
using (FileStream DestinationStream = File.Create(destinationFilePath))
{
await SourceStream.CopyToAsync(DestinationStream);
}
}
using (FileStream SourceStream = File.Open(sourceFilePath, FileMode.Open))
{
using (FileStream DestinationStream = File.Create(destinationFilePath))
{
await SourceStream.CopyToAsync(DestinationStream);
}
}
EdgarKa
EdgarKa2y ago
Yes, so the tool wouldn't wait for stuff to zip and just leave it to perform on the side.
Pobiega
Pobiega2y ago
sure just start your zipping, put their tasks in a list, then at the end before terminating you just await all the tasks in the list obviously at some point you need to let them finish, or you get weird behaviour
EdgarKa
EdgarKa2y ago
Might do, but I was thinking to leave Zip as only async one and perform other copyings and zipping at the same time
Becquerel
Becquerel2y ago
it will depend on whether your Zip method is async if it doesn't offer an awaitable method, you'll have to Task.Run it which won't be ideal
EdgarKa
EdgarKa2y ago
@Pobiega that makes sense. Will it work in the for/foreach loop?
Pobiega
Pobiega2y ago
can you show Zip()? this is very much implementation dependant Zip is properly async here, then yeah this will work, except that it will do one iteration of the loop at a time if you need it to start all the tasks at once, you'll need to have a list outside the loop you add the tasks to, and await after the loop
EdgarKa
EdgarKa2y ago
I've replicated as implementation is on other laptop, sorry 😅
Cisien
Cisien2y ago
.net has built in zip support
Want results from more Discord servers?
Add your server
More Posts