在我的应用程序中,我希望在选择根文件夹后添加添加Wireshark文件的选项。
我使用这个类来获取根文件夹中的所有文件(我有权访问的所有文件夹):
public static class SafeFileEnumerator
{
public static IEnumerable<string> EnumerateDirectories(string parentDirectory, string searchPattern, SearchOption searchOpt)
{
try
{
var directories = Enumerable.Empty<string>();
if (searchOpt == SearchOption.AllDirectories)
{
directories = Directory.EnumerateDirectories(parentDirectory).SelectMany(x => EnumerateDirectories(x, searchPattern, searchOpt));
}
return directories.Concat(Directory.EnumerateDirectories(parentDirectory, searchPattern));
}
catch (UnauthorizedAccessException ex)
{
return Enumerable.Empty<string>();
}
}
public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOpt)
{
try
{
var dirFiles = Enumerable.Empty<string>();
if (searchOpt == SearchOption.AllDirectories)
{
dirFiles = Directory.EnumerateDirectories(path).SelectMany(x => EnumerateFiles(x, searchPattern, searchOpt));
}
return dirFiles.Concat(Directory.EnumerateFiles(path, searchPattern));
}
catch (UnauthorizedAccessException ex)
{
return Enumerable.Empty<string>();
}
}
}点击Add directory按钮后:
private void btnAddDir_Click_1(object sender, EventArgs e)
{
string fileToAdd = string.Empty;
DialogResult dialog = folderBrowserDialog1.ShowDialog();
if (dialog == DialogResult.OK)
{
Editcap editcap = new Editcap();
foreach (string fileName in SafeFileEnumerator.EnumerateFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.AllDirectories))
{
if (editcap.isWiresharkFormat(fileName))
{
if (editcap.isLibpcapFormat(fileName))
{
listBoxFiles.Items.Add(fileName);
}
else if (!editcap.isLibpcapFormat(fileName))
{
listBoxFiles.Items.Add(editcap.getNewFileName(fileName));
}
}
}
}
}Editcap editcap = new Editcap(); -我的类,用于检查一个文件是否为有效的Wireshark文件,有两个方法:isWiresharkFormat和isLibpcapFormat。getNewFileName -如果文件不是pcap文件,则将其转换为pcap文件。
我想要的是在不同的线程中添加所有正确的文件(Wireshark文件)到我的列表框中,这样GUI就不会被阻止。理想情况下,在找到每个文件后,它会立即添加到我的列表框中,而不是等到所有文件都被评估之后。
发布于 2012-12-20 09:04:32
以下是使用Reactive Extensions回答您的问题的一种方法。
首先,将对RX库的引用和以下using语句添加到您的类定义中:
using System.Reactive.Linq;
using System.Reactive.Concurrency;然后,添加一个IDisposable私有字段,当您关闭应用程序并修改btnAddDir_Click_1方法时,该字段将用于清理所有剩余的线程工作,如下所示:
IDisposable _disposable;
private void btnAddDir_Click_1(object sender, EventArgs e)
{
string fileToAdd = string.Empty;
DialogResult dialog = folderBrowserDialog1.ShowDialog();
if (dialog == DialogResult.OK)
{
Editcap editcap = new Editcap();
var observable = SafeFileEnumerator.EnumerateFiles(folderBrowserDialog1.SelectedPath, "*.*", SearchOption.AllDirectories)
.ToObservable()
.SubscribeOn(NewThreadScheduler.Default);
_disposable = observable.Subscribe((fileName) =>
{
if (editcap.isWiresharkFormat(fileName))
{
if (editcap.isLibpcapFormat(fileName))
{
listBoxFiles.Items.Add(fileName);
}
else if (!editcap.isLibpcapFormat(fileName))
{
listBoxFiles.Items.Add(editcap.getNewFileName(fileName));
}
}
});
}
}在YourForm.Designer.cs中,正确处理_disposable对象:
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
//dispose the observable IDisposable
if (_disposable != null)
_disposable.Dispose();
base.Dispose(disposing);
}https://stackoverflow.com/questions/13959999
复制相似问题