1

私は Prism EventAggregator を見ていましたが、それは素晴らしいことです。私が最も懸念していたのは、スレッドを UI スレッドに正しくマーシャリングする機能でした。

この機能を使用して、BackgroundWorker と同様の方法でスレッドを作成するために使用できるクラスをモジュール開発者に提供できるかどうか疑問に思っていました。クラスのインターフェースは、

public interface IMyTask
{
    event DoWorkEventHandler DoWork;
    event RunWorkerCompletedEventHandler RunWorkerCompleted;
    void RunTaskAsync(object obj);
}

理解を深めるために、backgroundworker に似た型を保持しています。実装では、 taskstart および taskcomplete イベントを登録しています

public class TaskStartEventPayload
{
    public SubscriptionToken token { get; set; }
    public object Argument { get; set; }
}

public class TaskStartEvent : CompositePresentationEvent<TaskStartEventPayload>
{
}

public class TaskCompleteEventPayload
{
    public SubscriptionToken token { get; set; }
    public object Argument { get; set; }
    public object Result { get; set; }
}
public class TaskCompleteEvent : CompositePresentationEvent<TaskCompleteEventPayload>
{
}

MyTask クラスのコンストラクターで、完了が必要なスレッドを次のように取得します

 public MyTask(IEventAggregator eventAggregator, bool isUICompletion)
 {
       if (eventAggregator == null)
       {
                throw new ArgumentNullException("eventAggregator");
            }
            _eventAggregator = eventAggregator;
            _eventAggregator.GetEvent<TaskStartEvent>().Subscribe(TaskStartHandler, ThreadOption.BackgroundThread, false, new Predicate<TaskStartEventPayload>(StartTokenFilter));
            if(isUICompletion)
                _token = _eventAggregator.GetEvent<TaskCompleteEvent>().Subscribe(TaskCompleteHandler, ThreadOption.UIThread,true,new Predicate<TaskCompleteEventPayload>(CompleteTokenFilter));
            else
                _token = _eventAggregator.GetEvent<TaskCompleteEvent>().Subscribe(TaskCompleteHandler, ThreadOption.BackgroundThread, true, new Predicate<TaskCompleteEventPayload>(CompleteTokenFilter));
        }

ここでは、サブスクライブ中に取得したペイロードと同じトークンを持つペイロードがある場合にのみ、フィルター関数がイベントを返すフィルターに登録しています。

さらに私は使用します

 public void RunTaskAsync(object obj)
{
    //create payload
    _eventAggregator.GetEvent<TaskStartEvent>().Publish(payload);
}
public void TaskStartHandler(TaskStartEventPayload t)
{
     //fire dowork and create payload
     DoWork(this, args);
     _eventAggregator.GetEvent<TaskCompleteEvent>().Publish(tc);
}
public void TaskCompleteHandler(TaskCompleteEventPayload t)
{
    RunWorkerCompleted(this, args);
}

このクラスは次のように使用できます。

        MyTask et = new MyTaskagg, true);
        et.DoWork += new System.ComponentModel.DoWorkEventHandler(et_DoWork);
        et.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(et_RunWorkerCompleted);            
        et.RunTaskAsync("Test");

このアプローチで得られる利点は 1 です。threadpool を使用するため、backgroundWorker のようにスレッドを作成するオーバーヘッドがありません。2. RunWorkerCompleted が UI スレッドで実行される場合の適切なスレッド マーシャリング。

eventaggregator を Threader として使用することが正しいかどうかアドバイスをお願いします。

4

1 に答える 1

1

これは機能しますが、パフォーマンスをほとんど向上させるためにデバッグする必要があるコードです。私の意見では、マイクロ最適化は努力とサポート コストに値するものではありません。

EventAggregator は、アプリケーションのメッセージ バスとなることを意図しており、多くのコードをデバッグする必要がないように、本来の目的のために使用することを好みますが、それは私の個人的な好みです。

Event Aggregator は、これらのサブスクリプションをすべてクリーンアップするという意図よりも少しハードに動作する必要があります。これは、スレッド プーリングから得られるパフォーマンスの向上を超える可能性がありますが、それは単なる推測です。

于 2010-02-03T14:09:31.463 に答える