3

backgroundworker クラスで ProgressChanged イベントを非表示にすることは可能ですか?

継承するクラスを作成しましたSystem.ComponentModel.BackgroundWorkerが、複数のイベントが必要です: 私のクラスはオブジェクトのリストを処理し、(たとえば) オブジェクトが処理される前後にイベントが必要です。これらのイベントは、スレッド セーフであるため、Backgroundworker の ProgressChanged イベントから発生させます。呼び出し時に呼び出されるクラスのメソッドはReportProgress、パラメーターを使用して、起動するイベントを決定します。それはうまくいきます。

ここで、Backgroundworker を呼び出すクラスがイベントを直接サブスクライブできないようにする必要があります。ProgressChanged代わりに、私が提供する追加のイベントにのみサブスクライブできるようにする必要があります。

4

1 に答える 1

2

いくつかのアプローチがあります。

サブスクリプションを禁止し、発射を抑制

サブクラスは、(a) 呼び出し元がイベントに直接サブスクライブしようとした場合に例外をスローし、ProcessChange(b) イベントをまったく発生させないように記述できます。BackgroundWorker呼び出し元はサブクラスを a としてキャストし、イベントを直接サブスクライブできるため、(a) だけではイベントのサブスクライブが妨げられないことに注意してください。

class ExtendedBackgroundWorker : BackgroundWorker
{
    public new event ProgressChangedEventHandler ProgressChanges
    {
        add { throw new InvalidOperationException("This event cannot be added directly"); }
        remove {}
    }

    protected override void OnProgressChanged(ProgressChangedEventArgs e)
    {
        // do not call base.OnProgressChanged
    }
}

継承の代わりにコンポジションを使用する

ただし、可能であれば、まったく継承しない方がよい場合もありますBackgroundWorker。ABackgroundWorkerProgressChangedイベントを使用して進行状況の変化を報告します。そうでない場合、それは ではありませんBackgroundWorker。代わりに、BackgroundWorker をプライベート クラス メンバーとして実装し、必要に応じてメンバーからメンバーを公開することを検討してください。

class CustomBackgroundWorker : Component
{
    private BackgroundWorker worker;
    public event ProgressChangedEventHandler FirstEvent;
    public event ProgressChangedEventHandler SecondEvent;
    public event DoWorkEventHandler DoWork
    {
        add { worker.DoWork += value; }
        remove { worker.DoWork -= value; }
    }
    public event RunWorkerCompletedEventHandler RunWorkerCompleted
    {
        add { worker.RunWorkerCompleted += value; }
        remove { worker.RunWorkerCompleted -= value; }
    }

    public CustomBackgroundWorker()
    {
        worker = new BackgroundWorker();
        worker.ProgressChanged += OnProgressChanged;
        worker.WorkerReportsProgress = true;
    }

    public void RunWorkerAsync()
    {
        worker.RunWorkerAsync();
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        worker.Dispose();
    }

    private void OnProgressChanged(object o, ProgressChangedEventArgs e)
    {
        // code to handle progress change reports from the worker
    }
}

クライアントに役立つ Refire イベント

サブクラスは、イベントの使用を抑制するのではなく、他のイベントと組み合わせて (代わりとしてではなく) 使用して、サブスクライバーに関連情報 (たとえば、操作全体の進行状況) を提供できます。

于 2013-04-26T09:52:15.363 に答える