2017-03-22 53 views
0

我想在c#上构建一个win服务(无UI),它所做的全部工作是:在目录列表上运行并删除超过X kb的文件。 我想要更好的表现,什么是更好的方式来删除文件的条件

有什么更好的方法来做到这一点? 没有用于删除文件中没有纯粹的异步功能,所以如果我想使用异步等待 我可以换这样的功能:

public static class FileExtensions { 
    public static Task DeleteAsync(this FileInfo fi) { 
     return Task.Factory.StartNew(() => fi.Delete()); 
    } 
} 

,并调用这个函数,如:

FileInfo fi = new FileInfo(fileName); 
await fi.DeleteAsync(); 

我觉得像

foreach file on ListOfDirectories 
{ 

    if(file.Length>1000) 
     await file.DeleteAsync 

} 

但是在这个选项上,文件将会被1个1删除(并且每个DeleteAsync将在threadPool的线程中使用)。 ,所以我没有从异步赚,我可以通过1

也许我想去做1,收集名单X文件,然后删除它们进行AsParallel

请帮我找到更好的办法

+0

首先要优化将是*迭代之前'.Length' *过滤。 – Filburt

+1

Filburt已经说过,首先将所有文件都放入满足条件的列表中,然后在您的删除方法中使用'Parallel.ForEach'。 [MSDN](https://msdn.microsoft.com/en-us/library/dd992001(v = vs.110).aspx)有一个例子 –

+0

@MongZhu 为什么? 你想我会在所有的文件,并把ListForDelete,然后再次运行,并从列表中删除所有文件? 我不明白你在说什么,为什么 – FADI1987

回答

1

您可以使用Directory.GetFiles("DirectoryPath").Where(x=> new FileInfo(x).Length < 1000);来获取大小小于1 KB的文件列表。

然后使用Parallel.ForEach遍历该集合是这样的:

var collectionOfFiles = Directory.GetFiles("DirectoryPath") 
           .Where(x=> new FileInfo(x).Length < 1000); 

Parallel.ForEach(collectionOfFiles, File.Delete); 

可以这样说,你应该使用:

Parallel.ForEach(collectionOfFiles, currentFile => 
{ 
    File.Delete(currentFile); 
}); 

提高代码的可读性。

MSDN有关于如何使用Parallel.ForEach()

如果你想知道FileInfo对象一个简单的例子,这里是the documentation

+0

您需要增加'MaxDegreeOfParallelism',因为默认值对于此(IO绑定)任务来说太低。 – Evk

+0

@Evk Parallel.ForEach“发送”每个删除到另一个线程在另一个代码? 每次都不会花时间释放线程? 和defualt是不是我拥有的核心数量?为什么我需要增加 – FADI1987

+0

@ FADI1987我不认为它会发送每个项目到新的线程池线程。很可能它会将你的物品分成批次,然后在X线程上运行它们。但是你想增加线程的数量,因为你所做的是IO限制。默认情况下,线程的数量是内核的数量,当CPU工作时(某些数字处理),这很好。在你的情况下,如果你有比CPU核心更多的线程,你可以获得更好的性能,因为大多数线程只会处于阻塞状态,等待删除完成,并且不会工作。 – Evk

0

这可能可以帮助你。

public static class FileExtensions 
{ 
    public static Task<int> DeleteAsync(this IEnumerable<FileInfo> files) 
    { 
     var count = files.Count(); 
     Parallel.ForEach(files, (f) => 
     { 
      f.Delete(); 
     }); 
     return Task.FromResult(count); 
    } 
    public static async Task<int> DeleteAsync(this DirectoryInfo directory, Func<FileInfo, bool> predicate) 
    { 
     return await directory.EnumerateFiles().Where(predicate).DeleteAsync(); 
    } 
    public static async Task<int> DeleteAsync(this IEnumerable<FileInfo> files, Func<FileInfo, bool> predicate) 
    { 
     return await files.Where(predicate).DeleteAsync(); 
    } 

} 

enter image description here

enter image description here

 var _byte = 1; 
     var _kb = _byte * 1000; 
     var _mb = _kb * 1000; 
     var _gb = _mb * 1000; 
     DirectoryInfo d = new DirectoryInfo(@"C:\testDirectory"); 

     var deletedFileCount = await d.DeleteAsync(f => f.Length > _mb * 1); 
     Debug.WriteLine("{0} Files larger than 1 megabyte deleted", deletedFileCount); 
     // => 7 Files larger than 1 megabyte deleted 

     deletedFileCount = await d.GetFiles("*.*",SearchOption.AllDirectories) 
      .Where(f => f.Length > _kb * 10).DeleteAsync(); 

     Debug.WriteLine("{0} Files larger than 10 kilobytes deleted", deletedFileCount); 
     // => 11 Files larger than 10 kilobytes deleted 
相关问题