directory.GetFiles, как мне заставить его выплевывать элементы, когда он их находит? - PullRequest
5 голосов
/ 20 мая 2011

Я использую Directory.GetFiles, чтобы дать мне mp3-файлы, и я хотел бы заполнить ListBox результатами, но вместо того, чтобы останавливать программу, пока она проходит через метод, могу ли я заставить ее искатьи заполнить ListBox до получения mp3-файлов?

, так что я использую следующее (и не удается добавить их по одному за раз, он добавляет их все сразу, когдаэто сделано)

private List<string> Getmp3sFromFolders(string folder)
    {
       List<string> fileArray = new List<string>();

       try
       {
           DirectoryInfo dir = new DirectoryInfo(folder);
           var files = dir.EnumerateFiles("*.mp3");
           foreach (var file in files)
           {

               fileArray.Add(file.FullName);
               Dispatcher.BeginInvoke(_AddMP3ToListbox, file.Name);
           }

           var directories = dir.EnumerateDirectories();
           foreach (var subdir in directories)
           {
               fileArray.AddRange(Getmp3sFromFolders(subdir.FullName));

           }

          // lblFolderSearching.Content = folder.ToString();
       }
       catch
       {

       }
       return fileArray;
    }

я добавил _AddMP3ToListbox = AddMP3ToListbox

он действительно добавляет mp3 в список, но он делает это сразу, не сразу, как только находит,как я могу это исправить?

1 Ответ

11 голосов
/ 20 мая 2011

Используйте Directory.EnumerateFiles вместо Directory.GetFiles.EnumerateFiles вернет файлы в том виде, в каком они были найдены системой - не ждите, пока все они будут найдены.

Сделайте это в фоновом потоке и используйте Dispatcher.Invoke или Dispatcher.BeginInvoke для пользовательского интерфейса.поток, поскольку каждый найден, чтобы добавить его к ListBox.

Вот быстрый пример, который я бросил вместе.Вот XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ListBox x:Name="_FileList" />
        <Button Grid.Row="1" Content="Go!" Click="Button_Click" />
    </Grid>
</Window>

и вот код:

using System;
using System.IO;
using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Action<string> _AddToListBox;

        public MainWindow()
        {
            InitializeComponent();
            _AddToListBox = AddToListBox;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Action action = Go;
            action.BeginInvoke(null, null);
        }

        private void Go()
        {
            foreach (var file in Directory.EnumerateFiles(@"c:\windows\system32\"))
            {
                Dispatcher.BeginInvoke(_AddToListBox, file);
            }
        }

        private void AddToListBox(string toAdd)
        {
            _FileList.Items.Add(toAdd);
        }
    }
}

ни в коем случае не предполагается, что это будет наилучшим или всеобъемлющим примером.Просто показываю вам один способ сделать это.Кстати, я выбрал каталог system32 только потому, что в нем много файлов, чтобы я мог его протестировать.Тем не менее, на моей машине все еще работает почти мгновенно.

...