创建一个线程来处理特定类的事件

本文关键字:处理 事件 线程 一个 创建 | 更新日期: 2023-09-27 17:58:29

我有一个WPF应用程序,我需要监听并处理某个类的应用程序生命周期内的事件。

创建一个包装类,创建它的静态实例并调用"StartListening()",这是不是一种糟糕的做法?如果在这个静态实例上发生了未处理的异常,该怎么办?它会像在ASP.NET应用程序中那样删除整个应用程序吗?

我应该QueueUserWorkItem,创建类,附加事件,然后放入某种while(true){}语句来保持线程的活动性吗?

最佳实践是什么?

创建一个线程来处理特定类的事件

对我来说,这似乎是一个典型的发布者/侦听器问题。

我将创建一个接口:IMyClassNameEventListener,并使MyClass将其实例作为构造函数参数。然后在构造函数中,我将调用接口实例上的Attach(MyClass obj)方法。当然,监听器将有一个单例生命周期,它不需要是静态的。

一个稍微好一点的方法是使用工厂创建MyClass的实例,然后由其进行附加,因此Attach调用和依赖关系不在构造函数中。

应用程序是否会失败取决于你如何启动听众。您可以查看TaskFactory类,它提供了处理异常传播的选项。如果侦听器失败,您希望应用程序如何运行?

当然,在侦听器对象本身中,您只需要在有事情要处理时运行代码。因此,当您收到一个事件时,您启动了一个线程。如果希望只有一个线程在运行,则可以使用操作队列。

在侦听器类中,您可能希望有以下内容:

private Queue<Action> ActionQueue = new Queue<Action>();
private object LockObj = new Object();
private volatile bool IsRunning;
public void Attach(Class1 obj)
{
   obj.SomeEvent += this.HandleEvent;
}
private void HandleEvent(object sender, EventArgs e)
{
    lock(this.LockObj)
    {
        this.ActionQueue.Enque(() => this.Handle(sender, e));
        if (!this.IsRunning)
        {
           Task.Factory.StartNew(() => this.Loop() );
        }
    }
}
private void Loop()
{
    this.IsRunning = true;
    while ((Action action = this.DequeueAction()) != null)
        action();
    this.IsRunning = false;
}
private Action DequeueAction()
{
    lock (this.LockObj)
    {
        return this.ActionQueue.Count > 0 ? this.ActionQueue.Dequeue() : null;
    }
}
private void Handle(object sender, EventArgs e)
{
//handling code
}