Sdílet prostřednictvím


Postupy: Soubor adresáře s PLINQ iterovat

Tento příklad ukazuje dva způsoby jednoduché operace adresáře soubor parallelize. První dotaz používá GetFiles Metoda naplnit pole názvů souborů v adresáři a všech podadresářích. Tato metoda nevrátí až naplněna celé pole, a proto lze zavést čekací doba na začátku operace. Však po naplnění pole PLINQ můžete zpracovat paralelně velmi rychle.

Druhý dotaz používá statickému EnumerateDirectories a EnumerateFiles metod, které vrací výsledky okamžitě začít. Tento přístup může být rychlejší při jsou iterace velké adresářové stromy, přestože doba zpracování ve srovnání s prvním příkladu může záviset na mnoha faktorech.

Poznámka k upozorněníUpozornění

Tyto příklady jsou určeny pro využití prokázat a může běžet rychleji než ekvivalentní sekvenční LINQ dotazu objektů.Další informace o Vančurovou Principy Vančurovou v PLINQ.

Příklad

Následující příklad ukazuje jak iterovat přes soubor adresáře v jednoduchých situacích, pokud máte přístup ke všem adresářům ve stromu, jsou velmi velké velikosti souborů a časy přístupu nejsou významné. Tento přístup zahrnuje čekací doba na začátku období, zatímco zkonstruován pole názvů souborů.


struct FileResult
{
    public string Text;
    public string FileName;
}
// Use Directory.GetFiles to get the source sequence of file names.
public static void FileIteration_1(string path)
{       
    var sw = Stopwatch.StartNew();
    int count = 0;
    string[] files = null;
    try
    {
        files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
    }
    catch (UnauthorizedAccessException e)
    {
        Console.WriteLine("You do not have permission to access one or more folders in this directory tree.");
        return;
    }

    catch (FileNotFoundException)
    {
        Console.WriteLine("The specified directory {0} was not found.", path);
    }

    var fileContents = from file in files.AsParallel()
            let extension = Path.GetExtension(file)
            where extension == ".txt" || extension == ".htm"
            let text = File.ReadAllText(file)
            select new FileResult { Text = text , FileName = file }; //Or ReadAllBytes, ReadAllLines, etc.              

    try
    {
        foreach (var item in fileContents)
        {
            Console.WriteLine(Path.GetFileName(item.FileName) + ":" + item.Text.Length);
            count++;
        }
    }
    catch (AggregateException ae)
    {
        ae.Handle((ex) =>
            {
                if (ex is UnauthorizedAccessException)
                {
                   Console.WriteLine(ex.Message);
                   return true;
                }
                return false;
            });
    }

    Console.WriteLine("FileIteration_1 processed {0} files in {1} milliseconds", count, sw.ElapsedMilliseconds);
    }

Následující příklad ukazuje jak iterovat přes soubor adresáře v jednoduchých situacích, pokud máte přístup ke všem adresářům ve stromu, jsou velmi velké velikosti souborů a časy přístupu nejsou významné. Tento přístup začíná vyrábějící výsledky rychleji než v předchozím příkladu.


struct FileResult
{
    public string Text;
    public string FileName;
}

// Use Directory.EnumerateDirectories and EnumerateFiles to get the source sequence of file names.
public static void FileIteration_2(string path) //225512 ms
{
    var count = 0;
    var sw = Stopwatch.StartNew();
    var fileNames = from dir in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
                    select dir;


    var fileContents = from file in fileNames.AsParallel() // Use AsOrdered to preserve source ordering
                       let extension = Path.GetExtension(file)
                       where extension == ".txt" || extension == ".htm"
                       let Text = File.ReadAllText(file)
                       select new { Text, FileName = file }; //Or ReadAllBytes, ReadAllLines, etc.
    try
    {
        foreach (var item in fileContents)
        {
            Console.WriteLine(Path.GetFileName(item.FileName) + ":" + item.Text.Length);
            count++;
        }
    }
    catch (AggregateException ae)
    {
        ae.Handle((ex) =>
            {
                if (ex is UnauthorizedAccessException)
                {
                   Console.WriteLine(ex.Message);
                   return true;
                }
                return false;
            });
    }

    Console.WriteLine("FileIteration_2 processed {0} files in {1} milliseconds", count, sw.ElapsedMilliseconds);
}

Při použití GetFiles, zda máte dostatečná oprávnění pro všechny adresáře ve stromu. Jinak bude vyvolána výjimka a nebudou vráceny žádné výsledky. Při použití EnumerateDirectories PLINQ dotazu je problematický zpracování výjimek I/O bezproblémové způsobem, který umožňuje pokračovat iterace. Pokud I/O nebo neoprávněnému přístupu výjimky musí zpracovat váš kód, pak je vhodné metody popsané v Postupy: Soubor adresáře s paralelní třídy iterovat.

Pokud I/O čekací doba je problém, například s vstupně-výstupní operace přes síť, zvažte jednu asynchronního I/O technik popsaných v TPL a tradiční asynchronní programování v .NET a v tomto do blogu.

Viz také

Koncepty

Paralelní LINQ (PLINQ)

Historie změn

Datum

Poslední dokumenty

Důvod

Květen 2010

Byla přidána poznámka týkající se používání vs. Vančurovou.

Názory zákazníků