3

カスタム ファイル ダイアログを作成していますが、ロードに時間がかかりすぎるという問題があります。

ダイアログはプロパティで始まります。最初にディレクトリ ツリーをロードし、続いてバックグラウンド スレッドで残りのInitialDirectoryディレクトリをロードする方法を探しています。InitialDirectory

たとえば、InitialDirectoryがだった場合、C:\Users\User12345\MyDocumentsすべてのフォルダーをロードする必要があります

C:\
C:\ユーザー
C:\User12345
C:\Users\User12345\MyDocuments

次に、バックグラウンド スレッドを開始して、残りのすべてのディレクトリをロードします。

再帰を使用してInitialDirectory、アイテムを複製することなく、他の何よりも最初に をロードするための迅速かつ簡単な方法はありますか?

次のようなコードでフォルダーの存在を確認するとif (!Directory.Contains(f => f.FullName == folder.FullName))、負荷がかなり遅くなるため、これを行うための高性能な方法を見つけるのに苦労しています。

ディレクトリ全体をロードする現在のコードは次のようになります。

private void LoadDirectory()
{
    string root = @"C:\";
    var rootNode = new DirectoryModel() { Name = root, FullName = root };
    this.Directory.Add(rootNode);

    DirectoryInfo info = new DirectoryInfo(root);
    IEnumerable<DirectoryInfo> subDirectories = info.GetDirectories()
            .Where(d => ((d.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
                && ((d.Attributes & FileAttributes.System) != FileAttributes.System));

    LoadDirectories(subDirectories, root);
}

private void LoadDirectories(IEnumerable<DirectoryInfo> subDirs, string parentName)
{
    IEnumerable<DirectoryInfo> subdirectories;
    foreach (DirectoryInfo folder in subDirs)
    {
        var node = new DirectoryModel() { Name = folder.Name, FullName = folder.FullName, ParentName = parentName };

        Directory.Add(node);

        try
        {
            subdirectories = folder.GetDirectories("*", SearchOption.TopDirectoryOnly)
                .Where(d => ((d.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
                    && ((d.Attributes & FileAttributes.System) != FileAttributes.System));
        }
        catch (UnauthorizedAccessException e)
        {
            continue;
        }
        catch (System.IO.DirectoryNotFoundException e)
        {
            continue;
        }

        if (subdirectories.Count() != 0)
            LoadDirectories(subdirectories, folder.FullName);
    }
}

Directoryコレクションはフラット コレクションであることに注意してください。データ モデルに階層はありません。

4

2 に答える 2

3

それは、データをユーザーにどのように提示するかによって異なります。

コントロールを使用すると、すべてのデータをバックグラウンドでロードすることを簡単に回避できますが、ツリーのルートTreeViewのみをロードするだけです (私が理解している限り、既に行っているように)。

[+]このように、指定されたディレクトリのすべてのサブディレクトリ名とファイルをロードする手順を使用すると、ユーザーが興味のあるディレクトリの内容を表示するためにクリックするまで待つ必要があります。したがって、プロシージャを実行してツリーにデータを入力します。

これは、この種のものに対処するために私が知っている最もパフォーマンスの高い方法であり、実際には、ほとんどすべての「エクスプローラーのような」製品でこのパターンが見られます。ここでのパフォーマンスは、完全に洗練されたアルゴリズムではなく、より便利な動作モデルを定義することによって達成されました。

お役に立てれば。

于 2013-08-07T17:51:37.610 に答える
0

Tigran のソリューションに似せて、これを達成する 1 つの方法は、次のようなものを使用することです。

  1. ツリーの BeforeExpand イベントをサブスクライブします。

    private void BeforeExpand(object sender, BeforeExpandEventArgs e)
    {
        TreeListNode current = e.Node;
    
        if (current.Nodes.Count > 0)
            return;
    
        if (current.Tag is DriveInfo)
        {
            exampleTree.BeginUpdate();
            DriveInfo driveInfo = current.Tag as DriveInfo;
            LoadDirectories(current, driveInfo.RootDirectory);
            exampleTree.EndUpdate(true);
        }
        else if (current.Tag is DirectoryInfo)
        {
            exampleTree.BeginUpdate();
            LoadDirectories(current, (DirectoryInfo)current.Tag);
            exampleTree.EndUpdate(true);
        }
    }
    

そして、これが LoadDirectories() メソッドです。

    private void LoadDirectories(TreeListNode parent, DirectoryInfo directoryInfo)
    {
        DirectoryInfo[] directories = directoryInfo.GetDirectories();
        foreach (DirectoryInfo directory in directories)
        {
            if ((directory.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
            TreeListNode child = new TreeListNode() { Tag = directory, Text = directory.Name };
            parent.Nodes.Add(child);
        }

        FileInfo[] files = directoryInfo.GetFiles();
        foreach (FileInfo file in files)
        {
            TreeListNode child = new TreeListNode() { Tag = file, Text = file.Name };
            parent.Nodes.Add(child);
        }
    }

HTH、

-さいげ-

于 2013-09-03T13:02:40.363 に答える