我有一个 WPF 应用程序,我需要在某个类的应用程序生命周期内监听和处理事件。
创建包装类,创建它的静态实例并调用“StartListening()”是不好的做法吗?如果在这个静态实例上发生了未经处理的异常怎么办?它会像在 ASP.NET 应用程序中那样拆毁整个应用程序吗?
我应该使用 QueueUserWorkItem、创建类、附加事件,然后放置某种 while(true){} 语句来保持线程处于活动状态吗?
最佳做法是什么?
我有一个 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
}