0

BackgroundWorker を作成するフォームがあります。その後、ワーカーは何らかの作業を行い、ビジー状態のときに ReportProgress を実行してメッセージを UI に送り返します。次に、これらのメッセージを UI に記録します。ReportProgress は、「通知」と呼ばれるスレッド内の単一のメソッドによって実行されます。

ただし、スレッド内では、静的クラスを呼び出してファイル アクセス タイプの作業を行います。その静的クラスも進行状況を報告する必要があります...そのため、静的クラスを呼び出したスレッド クラスの Notify メソッドを呼び出す必要がありますが、呼び出し元のクラス内のメソッドにはアクセスできません。

したがって、UI はスレッドを作成し、スレッドはクラスを使用しますが、クラス内の Notify メソッドを静的クラスから呼び出す必要があります。これどうやってするの?

これは遠くへの私の試みです。アイデアは、デリゲートを使用しようとすることです...しかし、私は実際にデリゲートを使用することに行き詰まっています。:)

私のスレッドクラスには、次のメソッドがあります。

public void Notify(string message, Constants.ErrorLevel errorLevel)
{
    var su = new StatusUpdate {StatusMessage = message, ErrorLevel = 0};
    _bw.ReportProgress(0, su);
}

これは機能しています。呼び出し元の UI に適切に報告します。

このクラスでデリゲートを作成しました。

public delegate bool NotificationsDelegate(object MessageHolder);

ファイル管理を処理するための静的クラスを非静的に変更し、作成時にそのデリゲートをファイル マネージャー クラスに渡したいと考えています。

public class FileManager
{
private readonly NotificationsDelegate _notifications;

public FileManager(NotificationsDelegate notifications)
{
    _notifications = notifications;
}

private void SendMessageBack(string p, ConsoleColor consoleColor)
{
    var su = new StatusUpdate {ErrorLevel = 0, StatusMessage = p};
    _notifications(su);
}

それで、私はそれを作成し、通知デリゲートを渡します...そして、私の「SendMessageBack」メソッドで、デリゲート(_notificationsと呼ばれます)を呼び出すことを望みます。

しかし、それは私が立ち往生しているところです。デリゲートはまだ通知メソッドに割り当てられていません。私はイベントに慣れていないので、自分のやり方を推測しています。しかし、誰かがこれを正しくするのを手伝ってくれますか?

4

2 に答える 2

1

私はあなたが何をしているのか確信が持てませんがNotify、ファイルアクセスワーククラスからメソッドを呼び出すためのイベントベースの通知システムを見てみたいと思います. FileManagerファイル アクセス ワーク クラスが呼び出され、それがインスタンス クラスであると想定しています。

まず、カスタムEventArgクラスを作成して、クラスから送信される通知に中継するデータを格納しますFileManager。メソッドを更新する場合は、このカスタム クラスを使用DoNotifyするクラスでイベントを作成し、(ステータス データを入力した後に) イベントを呼び出します。FileManagerEventArgNotify

オブジェクトをインスタンス化FileManagerしてイベントをサブスクライブし、DoNotifyそのハンドラーでメソッドを呼び出すと、次のようになりますNotify

public class FileManager
{
    public event EventHandler<NotifyEventArgs> DoNotify;

    private void DoSomethingInterestingMethod() {
        //...

        // Let listeners know something interesting happened.
        var doNotify = DoNotify;
        if (doNotify != null) {
            doNotify(this, new NotifyEventArgs(errorLevel, message));
        }

       //...
    }
}

public class NotifyEventArgs : EventArgs
{
    public NotifyEventArgs(int errorLevel, string statusMessage) {
        ErrorLevel = errorLevel;
        StatusMessage = statusMessage;
    }

    public int ErrorLevel { get; private set;}
    public string StatusMessage { get; private set; }
}

次に、BackgroundWorker スレッド ( DoWork(?) 内) で 1 つ以上のオブジェクトを作成し、イベントFileManagerをサブスクライブします。DoNotify

var fm = new FileManager();
fm.DoNotify += FileManager_Notify;

DoNotify ハンドラーでメソッドを呼び出しますNotify

void FileManager_Notify(object sender, NotifyEventArgs e) {
    Notify(e.ErrorLevel, e.StatusMessage);
}

実装の詳細の一部については完全には確信が持てないので、このアプローチを評価して、それが適切かどうかを判断できるように、十分に明確にしていただければ幸いです。

于 2013-04-18T05:38:25.547 に答える