Here is my effort to implement extensions for FileInfo
object:
public static class FileExtensions
{
public static async Task MoveFileAsync(this FileInfo file, string destinationPath, string destinationFileName = "")
{
await CopyFileAsync(file, destinationPath, destinationFileName).ContinueWith((x) =>
{
DeleteFileAsync(file);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}
public static async Task CopyFileAsync(this FileInfo file, string destinationPath, string destinationFileName = "")
{
if (string.IsNullOrWhiteSpace(destinationFileName))
{
destinationFileName = file.Name;
}
using (FileStream SourceStream = file.Open(FileMode.Open))
{
using (FileStream DestinationStream = File.Create(Path.Combine(destinationPath, destinationFileName)))
{
await SourceStream.CopyToAsync(DestinationStream);
}
}
}
public static Task DeleteFileAsync(this FileInfo file)
{
return Task.Run(() =>
{
if (File.Exists(file.FullName))
{
File.Delete(file.FullName);
}
});
}
}
The idea was to make it efficient, and basically, allow deleting in the background.
It feels like I mix things, but not sure what exactly is wrong.
So, I have a couple of questions for the beginning:
The implementation of
MoveFileAsync
:- Is this the right way to implement it? I wanted to call the
CopyFileAsync
and when it is completed -> callDeleteFileAsync
. - Do I need to add
return
beforeDeleteFileAsync(file);
? (So that the method will return a task).
- Is this the right way to implement it? I wanted to call the
The next step is using this
DeleteFileAsync
method within a loop. Like this:
public Task EmptyWorkingFolder()
{
var directory = new DirectoryInfo(/*my-directory-path*/);
var deleteTasks = new List<Task>();
foreach (FileInfo file in directory.EnumerateFiles())
{
deleteTasks.Add(file.DeleteFileAsync());
}
return Task.WhenAll(deleteTasks);
}
Now my question is, how useful is this in comparison to just deleting the files synchronously?
if (File.Exists(file.FullName))
a redundant check, look intoFile.Delete
documentation. 2) there's no sense to make disk operations concurrent because file system anyway does all the jobs sequentially for single drive. Run oneTask
for all the Delete operations if you need toawait
it. Measure and compare the performance of the different implementations to be sure. 3) don't mix continuations with async/await approach. 4) names for the local variables must begin with lower-cased letter. \$\endgroup\$await CopyFileAsync(file, destinationPath, destinationFileName).ContinueWith((x) => { DeleteFileAsync(file); }, TaskContinuationOptions.OnlyOnRanToCompletion);
can be thisawait CopyFileAsync(file, destinationPath, destinationFileName); DeleteFileAsync(file);
with exactly the same behavior. Continuations and async/await provides the same features but simply looks differently. Mixed code is harder to read. \$\endgroup\$await
s in a row (for copy and for delete). So I think that it's better to useTask.WhenAll()
to prevent losing errors. \$\endgroup\$