0

私のアプリケーションでは、ルートフォルダを選択した後に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>();
        }
    }
}

[ディレクトリの追加]ボタンをクリックした後:

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();-ファイルが2つのメソッドを持つ有効なWiresharkファイルであるかどうかをチェックする私のクラス:isWiresharkFormatisLibpcapFormatgetNewFileName-ファイルがpcapファイルでない場合は、pcapファイルに変換されます。

私が欲しいのは、GUIがブロックされないように、リストボックスに追加されたすべての正しいファイル(Wiresharkファイル)を別のスレッドで追加することです。理想的には、各ファイルが見つかった後、すべてのファイルが評価されるまで待たずに、すぐにリストボックスに追加されます。

4

1 に答える 1

1

これは、を使用する質問へのアプローチ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);
}
于 2012-12-20T01:04:31.500 に答える