2

我有一个类,我认为制作静态更有意义,因为它基本上是一个实用程序类。作为本课程的一部分,我正在与 Microsoft Access 和 Microsoft Excel 进行互操作。

显然,Office Interop 对象是非托管资源,静态类不能有析构函数。我觉得只有一个Excel.Application对象实例和Access.Application我的各种方法可以使用的对象实例是有意义的,注意关闭我的数据库和工作簿,并适当地处理错误。

当我关闭程序时,我的问题就出现了,如果我不运行System.Runtime.InteropServices.Marshal.ReleaseComObject("myOfficeApplicationInstance");,Office 实例会在我的任务管理器中徘徊。如果我在我的应用程序运行时释放该对象,那么我将无法再次使用它。

我不确定这一切是否有意义,所以下面有一些代码:

using System;
using Excel = Microsoft.Office.Interop.Excel.Application;
using Access = Microsoft.Office.Interop.Access.Application;

namespace QWERTY
{
    internal static class CreateReport
    {
        private static readonly Excel _excel;
        private static readonly Access _access;

        static CreateReport()
        {
            _excel = new Excel();
            _access = new Access();
        }

        internal static void Performance(DateTime reportDate)
        {
            _excel.Workbooks.Open(@"C:\whatever.xlsx");

            //Do stuff with Excel

            _excel.Workbooks.Close();

            _access.OpenCurrentDatabase(@"C:\whatever.accdb");

            //Do stuff with Access

            _access.CloseCurrentDatabase();
        }
    }
}

几个问题

  1. 我对这应该是一个静态类吗?
  2. 使用完静态类后如何处理非托管资源?
4

4 回答 4

2

There are no static finalizers (see here). If you want to make the class static, also add a method to clean up which you call at the end of you application.

An alternative (which I would prefer) is to have a singleton instance, and clean up this instance at the end of your application.

You can also then have a static property to access the instance if you want to. An alternative to the static property is to use some form of DI which you configure to create a single instance. Most DI's offer singleton scopes.

于 2012-09-14T08:36:28.713 回答
2

如果您希望采用静态方式实现继承CriticalFinalizerObject 类的类。将您的静态类清理放在它的终结器中,然后将该类的一个实例添加为您的静态类的一个字段。然后,如果应用程序退出或您的应用程序域卸载该实例终结器将运行清理静态类。

于 2012-09-14T10:45:00.757 回答
1

处理非托管资源的最佳方法是将它们包装在实现 IDisposable 的类中。然后,您应该在 using 块中使用该类以确保正确清理。由于所有包含 IDisposable 成员的类本身都应该是 IDisposable,因此将它们设置为静态类成员并不是一个好主意。

当你的应用程序退出时,你总是可以释放它们,你确实有那个事件。

您确定不能在应用程序中打开 Excel 两次吗?

于 2012-09-14T08:30:12.977 回答
0

抱歉,Office 互操作对象被视为托管资源,因为 Excel 和 Access 不实现 Idisposable 接口。

您是否尝试使用Excel.Quit语句正确关闭您的应用程序?我在您发布的代码中没有看到它。

于 2015-03-29T15:11:38.743 回答