Je regardais Prism EventAggregator et son 'génial. La partie que j'étais le plus inquiet était sa capacité de marshaler le fil correctement au fil d'interface utilisateur. Je me demandais si je pouvais utiliser cette capacité pour fournir aux développeurs de modules une classe qui pourrait être utilisée pour créer des threads de la même manière que BackgroundWorker. Interface de classe peut être un peu semblable àCan Prism EventAggregator peut-il être utilisé pour les besoins de filetage?
public interface IMyTask
{
event DoWorkEventHandler DoWork;
event RunWorkerCompletedEventHandler RunWorkerCompleted;
void RunTaskAsync(object obj);
}
J'ai gardé des types similaires à BackgroundWorker pour une meilleure compréhension. En application je suis inscris taskstart et événements 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>
{
}
Dans le constructeur pour la classe MyTask je prends quel fil l'achèvement est nécessaire en tant que
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));
}
ici je suis inscris avec des filtres où renvoie la fonction de filtre l'événement seulement s'il a Payload a le même jeton que lors de l'abonnement.
plus loin, j'utiliser
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);
}
Cette classe peut être utilisé comme
MyTask et = new MyTaskagg, true);
et.DoWork += new System.ComponentModel.DoWorkEventHandler(et_DoWork);
et.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(et_RunWorkerCompleted);
et.RunTaskAsync("Test");
avantage que je vois dans cette approche est 1. Il utilise threadpool donc pas de frais généraux de créer des fils comme dans BackgroundWorker. 2. Assemblage de threads correct dans le cas où RunWorkerCompleted doit être exécuté sur un thread UI.
Veuillez indiquer si cela est correct d'utiliser eventaggregator comme Threader.