Commenter TaW의 제안에 따라 진행 과정의 기초로 사용할 디렉토리를 계산할 수 있다는 것이 좋습니다. 그러나 제안 자체가 아니라 코드가 구현 된 것처럼 보이는 작은 문제가 있습니다.
귀하의 질문에 무엇이 PortableDeviceFolder
인지 분명하지 않습니다. 그러나 파일과 폴더의 차이점을 추상화하여 모두 Files
속성에서 반환합니다. 처리에 가장 시간이 많이 걸리는 부분은 특정 디렉토리의 파일 이름을 실제로 검색 할 가능성이 높기 때문에 PortableDeviceFolder
메커니즘 만 주어진 디렉토리의 디렉토리를 반환해야하는 경우 Files
속성을 사용해야합니다. 카운트를 생성 할 목적으로 반환 된 파일을 무시하고 디렉토리와 함께 모든 파일을 열거합니다.
즉, 계산식을 얻는 데는 지정된 이름을 실제로 검색하는 시간이 소요됩니다.
그래서,이 답변의 목적을 위해 나는 PortableDeviceFolder
클래스 단지 디렉토리 자체를 반환 다른 특성 Folders
이 있다고 가정합니다. 그런 재산으로, 우리는 TaW가 제안한 제안을 이용할 수 있습니다.
먼저 해당 카운트를 얻어야합니다. 이 작업을 수행하는 방법은 다음과 같을 것이다 :
이
private int CountFolders(PortableDeviceFolder rootFolder)
{
return rootFolder.Folders.Select(folder => CountFolders(folder)).Sum() + 1;
}
약간의 지연이있을 것입니다 진행 과정이 표시되기 전에, 물론 위 걸리는 시간을 예측하는 유용한 방법이 없기 때문입니다. 그러나 우리는 모든 파일이 아닌 디렉터리 만 찾고 있기 때문에 상대적으로 간단해야합니다.
처리가 진행되는 동안 진행 상황을 업데이트하려면 별도의 스레드에서 검색을 실행하고 Dispatcher.Invoke()
을 사용하여 ProgressBar.Value
속성을 업데이트해야합니다. 검색 방법은 다음과 같습니다
private void SearchFolder(PortableDeviceFolder parent,
List<PortableDeviceFolder> result, string fileName, IProgress<int> progress)
{
foreach (var item in parent.Files)
{
PortableDeviceFolder folder = item as PortableDeviceFolder;
if (folder != null)
{
SearchFolder(folder, result, fileName, progress);
}
else if (item.Name.Equals(fileName, StringComparison.OrdinalIgnoreCase))
{
result.Add(parent);
}
}
progress.Report(1);
}
참고 :별로 참고 문헌 result
매개 변수를 전달하고 왜 나에게 분명하지 않다. 그건 필요하지 않은 것 같아서, 나는 그것을 정기적 인 by-value 매개 변수로 변경했다. 당신의 UI 코드에서
,이처럼 호출 할 수 있습니다 : 여기에 우리가 작업이 수행되는 동안 CountFolders()
과 SearchFolder()
방법은 비동기, UI를 보장하는 것은 반응 남아 모두 실행
private async void SearchFolder_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
button.IsEnabled = false;
string searchPath = textBlock1.Text, searchText = textBox1.Text;
List<PortableDeviceFolder> folders = new List<PortableDeviceFolder>();
PortableDeviceFolder rootFolder = new WindowsDirectoryFolder(searchPath);
progressBar1.Value = 0;
progressBar1.Maximum = await Task.Run(() => CountFolders(rootFolder));
Progress<int> progress =
new Progress<int>(increment => progressBar1.Value += increment);
await Task.Run(() => SearchFolder(rootFolder, folders, searchText, progress));
listBox1.ItemsSource = folders;
button.IsEnabled = true;
}
참고.
위의 내용은이 기술을 설명하기 위해 작성한 간단한 WPF 프로그램에서 가져 왔지만 Winforms 나 다른 GUI 프레임 워크에 어려움없이 적용 할 수 있습니다. 기본 아이디어는 동일하게 유지됩니다.
필자는 재귀 깊이를 알려주는 새로운 'int'매개 변수를 메서드 시그니처에 추가하여 각 레벨 전체에서 차지하는 비율을 알 수 있다고 생각합니다. – adv12
@ adv12 그러나 재귀 깊이가 충분하지 않다는 것을 알고, 정확한 분수를 얻으려면 각 디렉토리에 몇 개의 파일이나 폴더가 있는지 알아야합니다. – j0h4nn3s
동의. 둘 다 필요합니다. – adv12