私は 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 として使用することが正しいかどうかアドバイスをお願いします。