3

問題のダスティン・キャンベルの答えでイベントから値を返す - これには良い習慣がありますか? イベント ハンドラーからデータを返す代わりに、WinForms FormClosing イベントの Cancel プロパティと同様のイベントに渡されるカスタム EventArgs のセットに書き込み可能なプロパティを持つことができると述べられています。

EventArgs のプロパティを使用して、イベントの呼び出し元にフィードバックを提供するにはどうすればよいですか?

私の特定のシナリオは、実行する Controller クラスがあり、実行Job Aを要求する多くのクラスがあるJob Aということです。したがって、コントローラーはすべてのクラスでこのイベントにサブスクライブされます。

仕事が完了したことを発信者にフィードバックしたいと思います。注意が必要なのは、これらのクラスはモジュールのようなものであり、コントローラーはそれらについて何も知らないということです。

writable propertyただし、コントローラーがそれを介してフィードバックを提供できるように、イベントのデリゲートにそれを含めることです。このプロパティは、リフレクションを使用して何らかの方法で呼び出すことができますが、これは私のシナリオでは問題ありません。

4

1 に答える 1

1

デリゲートのプロパティを定義することはできません。また、そのようなメカニズムにはリフレクションは必要ありません。やりたいことは、EventArgs派生クラスで「戻り値」プロパティを定義することです。

そのような単純なクラスは次のようになります。

public class JobEventArgs : EventArgs {
  public bool Done { get; set; }
}

これで、クラスでイベントを次のように宣言できます。

public event EventHandler<JobEventArgs> Job;

イベントを処理するメソッドでの使用:

public void DoJob(object s, JobEventArgs args) {
  // do stuff
  args.Done = true;
}

そしてコードを呼び出すイベントでは:

public void FireJobEvent() {
  var args = new JobEventArgs();

  this.Job(this, args);

  if(!args.Done) {
    // the job was not handled
  }
}

しかし、率直に言って、完了時に通知を使用して非同期でジョブを実行したいようです。

その結果、次のような構文になります..

class Module {
  public void JobCompleted(IAsyncResult r) {
    if(!r.IsCompleted)
      return;

    Console.WriteLine("The job has finished.");
  }

  public void ExecuteJob() {
    var job = new EventArgs<JobEventArgs>((s, a) => { this.controller.JobA(); });
    job.BeginInvoke(null, null, 
      r => 
      { 
        this.JobCompleted(r); 
        if(r.IsCompleted) 
          job.EndInvoke(r); 
      }, null);
  }
}
于 2012-11-22T02:13:14.043 に答える