2017-03-22 94 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 
相關問題