【问题标题】:How to subscribe to application shutdown event in class library如何订阅类库中的应用程序关闭事件
【发布时间】:2011-08-03 08:12:33
【问题描述】:

某个应用程序使用了一个类库。它包含一个供外部使用的类 A,以及库内另一个私有类 B 的静态字段。用户应用程序使用库中的 A 类实例。

由于应用程序关闭,我想在 B 类中进行一些清理。 是否可以在没有用户应用程序任何操作的情况下捕获 B 类中的应用程序关闭事件?

class B
{
    public B()
    {
        // attach Handler() to applicaiton shutdown event
    }

    void Handler()
    {
        // do some work
    }
}

【问题讨论】:

    标签: c# events class-library subscription application-shutdown


    【解决方案1】:
    using System.Windows.Forms;
    
    public class B
    {
        public B()
        {
            Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
        }
    
        void Application_ApplicationExit(object sender, EventArgs e)
        {
            //do cleanup of your class
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果我理解正确,您的模型如下所示:

      然后您希望ClassB 通过ClassAApplication 通信,如下所示:

      从面向对象设计的角度来看,这违反了Law of Demeter,其中规定对象只能与其直接邻居对话。在这方面,如果可能的话,我建议您在ClassA 中进行清理。

      从实现的角度来看,我会让ClassA 通过在构造函数中获取Application 的实例来明确声明其对Application 的依赖关系。这样您就可以轻松订阅ApplicationClassA 内发布的任何事件,或者,可能是ClassBinner classes in C# can access the outer class' private members 以来发布的任何事件:

      public class A
      {
          private readonly Application application;
      
          public A(Application application)
          {
              if (application == null)
              {
                  throw new ArgumentNullException("application");
              }
      
              this.application = application;
              this.application.ApplicationExit += application_ApplicationExit;
          }
      
          private void application_ApplicationExit(object sender, EventArgs e)
          {
              // Perform cleanup
          }
      }
      

      【讨论】:

      • 不,交互路径是app->A->B 没有反向路径,B类自己运行并在一个线程中从db中获取一些数据并与它的mem同步。数据库的 A 类查询 B 保存在其内存中
      • App 有 A 实现的接口对象,它是只有一个 FindAll() 函数的存储库,我需要 B 中的应用关闭事件来同步 mem 和 db
      • @Chesnokov Yuriy 订阅由另一个类发布的事件会在订阅者和发布者之间建立强大的关联。从这个意义上说,如果ClassB 订阅了Application 发布的事件,那么ClassB 的对象对Application 对象具有很强的依赖性。我仍然认为这种关联应该在设计中明确说明,以提高对更改可能导致的任何可能的副作用的认识。
      • 我明白了,那么析构函数 ~B() 是捕获它的正确位置,因为 B 在 A 中被声明为静态字段并且只会被调用一次。我试过了,但是因为析构函数被称为记录器,所以它的观察者被处理了,并且日志消息没有被保存。我需要进一步调试问题
      • ~B() 在程序流从 Program.Main() 返回后调用,其中所有日志记录已完成,无法将 ~B() 的结果保存到日志
      猜你喜欢
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 2023-03-12
      相关资源
      最近更新 更多