Можно ли использовать Prism EventAggregator для работы с потоками? - PullRequest
1 голос
/ 03 февраля 2010

Я смотрел на Prism EventAggregator и его 'отлично. Больше всего меня беспокоило то, что он способен правильно распределять потоки в потоках пользовательского интерфейса.

Мне было интересно, смогу ли я использовать эту возможность, чтобы предоставить разработчикам модулей класс, который можно использовать для создания потоков аналогично BackgroundWorker. Интерфейс класса может быть несколько похож на

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

Для лучшего понимания я сохранил типы, аналогичные фоновому. В реализации я регистрирую события 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. Он использует пул потоков, поэтому нет необходимости создавать потоки, как в backgroundWorker. 2. Правильная сортировка потока в случае, если RunWorkerCompleted будет выполняться в потоке пользовательского интерфейса.

Пожалуйста, дайте совет, если было бы правильно использовать Eventaggregator в качестве Threader.

1 Ответ

1 голос
/ 03 февраля 2010

Это будет работать, хотя это код, который вы должны отлаживать для очень небольшого прироста производительности.На мой взгляд, микрооптимизация редко стоит усилий и затрат на поддержку.

EventAggregator предназначен для шины сообщений для вашего приложения, и я обычно предпочитаю использовать вещи для их первоначального намерения, иначе мне придется отлаживать много кода, но это мое личное предпочтение.

Агрегатору событий придется работать немного сложнее, чем предназначено для очистки всех этих подписок, что, вероятно, превысит любой выигрыш в производительности, который вы получите от пула потоков, но это всего лишь предположение.

...