创建一个线程来处理特定类的事件
本文关键字:处理 事件 线程 一个 创建 | 更新日期: 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
}