2010-02-03 5 views
1

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.

Répondre

1

Cela fonctionnera, bien que ce soit le code que vous devez déboguer pour un gain de performance très faible. Micro-optimisation vaut rarement l'effort et les coûts de soutien à mon avis. EventAggregator est destiné à être un bus de messages pour votre application et je préfère généralement utiliser les choses pour leur intention d'origine, de peur que je doive déboguer beaucoup de code, mais c'est ma préférence personnelle. L'aggrégateur d'événements va devoir travailler un peu plus fort que pour nettoyer tous ces abonnements, ce qui dépassera probablement tout gain de performance que vous obtiendrez du pool de threads, mais ce n'est qu'une approximation.