Prism EventAggregator 可以用于满足线程需求吗?

发布于 2024-08-19 22:31:44 字数 2909 浏览 1 评论 0原文

我正在查看 Prism EventAggregator,它非常棒。我最关心的是它正确地将线程编组到 UI 线程的能力。

我想知道是否可以使用此功能为模块开发人员提供一个类,该类可用于以与 BackgroundWorker 类似的方式创建线程。类的接口可以有点类似于

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

我保留了类似于backgroundworker的类型以便更好地理解。在实现中,我正在注册任务启动和任务完成事件

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));
        }

这里我正在向过滤器注册,其中过滤器函数仅当 Payload 具有与 get while 相同的令牌时才返回事件订阅。

进一步我使用

 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 在 UI 线程上执行。

请告知使用 eventaggregator 作为 Threader 是否正确。

I was looking at Prism EventAggregator and its' great. I part i was most concerned was its capability to marshal thread correctly to UI thread.

I was wondering if i can use this capability to provide module developers a class which could be used to create threads in a similar way as BackgroundWorker. Interface of class can be somewhat similar to

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

I have kept types similar to backgroundworker for better understanding. In implementation i am registering taskstart and taskcomplete events

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>
{
}

In the constructor for the MyTask class i take which thread the completion is required on as

 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));
        }

here i am registering with filters where filter function returns the event only if it has Payload has same token as while got while subscribing.

further I use

 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);
}

This class can be used as

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

Benefit I see in this approach is
1. It uses threadpool so no overhead of creating threads as in backgroundWorker.
2. Proper thread marshalling in case RunWorkerCompleted to be executed on UI thread.

Please advice if this would be correct to use eventaggregator as Threader.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

べ映画 2024-08-26 22:31:44

这是可行的,尽管您必须调试它的代码以获得很少的性能增益。在我看来,微观优化很少值得付出努力和支持成本。

EventAggregator 旨在成为应用程序的消息总线,我通常更喜欢按照其初衷使用事物,以免我必须调试大量代码,但这是我个人的偏好。

事件聚合器将不得不比原本要清理所有这些订阅更加努力,这可能会超过您从线程池获得的任何性能增益,但这只是一个猜测。

This will work, although it's code you have to debug for very little performance gain. Micro-optimizing is rarely worth the effort and support costs in my opinion.

EventAggregator is meant to be a message bus for your application and I typically prefer to use things for their original intention, lest I have to debug a lot of code, but that's my personal preference.

Event Aggregator is going to have to work a little harder than it is meant to cleaning up all of those subscriptions, which will likely exceed any performance gain you get from the thread pooling, but that is just a guess.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文