Using Wrapper objects to Properly clean up excel interop objects

前端 未结 5 1097
滥情空心
滥情空心 2021-02-20 02:39

All of these questions:

  • Excel 2007 Hangs When Closing via .NET
  • How to properly clean up Excel interop objects in C#
  • How to properly clean up inte
5条回答
  •  终归单人心
    2021-02-20 03:27

    What I'd do:

    class ScopedCleanup : IDisposable where T : class
    {
        readonly Action cleanup;
    
        public ScopedCleanup(T o, Action cleanup)
        {
            this.Object = o;
            this.cleanup = cleanup;
        }
    
        public T Object { get; private set; }
    
        #region IDisposable Members
    
        public void Dispose()
        {
            if (Object != null)
            {
                if(cleanup != null)
                    cleanup(Object);
                Object = null;
                GC.SuppressFinalize(this);
            }
        }
    
        #endregion
    
        ~ScopedCleanup() { Dispose(); }
    }
    
    static ScopedCleanup CleanupObject(T o, Action cleanup) where T : class
    {
        return new ScopedCleanup(o, cleanup);
    }
    
    static ScopedCleanup CleanupComObject(ComType comObject, Action actionBeforeRelease) where ComType : class
    {
        return
            CleanupObject(
                comObject,
                o =>
                {
                    if(actionBeforeRelease != null)
                        actionBeforeRelease(o);
                    Marshal.ReleaseComObject(o);
                }
            );
    }
    
    static ScopedCleanup CleanupComObject(ComType comObject) where ComType : class
    {
        return CleanupComObject(comObject, null);
    }
    

    Usage case. Note the call to Quit, which seems to be necessary to make the process end:

    using (var excel = CleanupComObject(new Excel.Application(), o => o.Quit()))
    using (var workbooks = CleanupComObject(excel.Object.Workbooks))
        {
            ...
        }
    

提交回复
热议问题