1

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

创建包装类,创建它的静态实例并调用“StartListening()”是不好的做法吗?如果在这个静态实例上发生了未经处理的异常怎么办?它会像在 ASP.NET 应用程序中那样拆毁整个应用程序吗?

我应该使用 QueueUserWorkItem、创建类、附加事件,然后放置某种 while(true){} 语句来保持线程处于活动状态吗?

最佳做法是什么?

4

1 回答 1

1

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

我将创建一个接口: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
}
于 2013-02-10T18:46:08.703 回答