ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

COM对象释放辅助类

2022-04-27 20:00:06  阅读:167  来源: 互联网

标签:释放 return expr mce Walk Add obj 辅助 COM


 

/*
  com组件,object对象释放,
  ref: https://www.codenong.com/2191489/
  using (var coms = new ReleaseWrapper())
  {
    var fso = coms.Add(new FileSystemObject());
    var dir1 = coms.Add(() => new FileSystemObject().Drives["c"].RootFolder);

  }
  */
class ReleaseWrapper : IDisposable
{
  readonly List<object> m_Coms = new List<object>();
  readonly List<IDisposable> m_NetObjs = new List<IDisposable>();
  public T Add<T>(Expression<Func<T>> func)
  {
    return (T)Walk(func.Body);
  }
  public T Add<T>(T obj)
  {
    if (obj != null)
    {
      if (Marshal.IsComObject(obj))
      {
        m_Coms.Add(obj);
      }
      else
      {
        IDisposable iDis = obj as IDisposable;
        if (iDis != null)
        {
          m_NetObjs.Add(iDis);
        }
      }
    }
    return obj;
  }
  object Walk(Expression expr)
  {
    return  WalkImpl(expr);
  }
  object[] Walk(IEnumerable<Expression> args)
  {
    if (args == null) return null;
    return args.Select(arg => Walk(arg)).ToArray();
  }
  object WalkImpl(Expression expr)
  {
    Debug.WriteLine(expr?.NodeType);
    //Debug.WriteLine(expr.ToString());

    switch (expr.NodeType)
    {
      case ExpressionType.Constant:
        return ((ConstantExpression)expr).Value;
      case ExpressionType.New:
        NewExpression ne = (NewExpression)expr;
        return ne.Constructor.Invoke(Walk(ne.Arguments));
      case ExpressionType.MemberAccess:
        MemberExpression me = (MemberExpression)expr;
        object target = Walk(me.Expression);
        switch (me.Member.MemberType)
        {
          case MemberTypes.Field:
            return ((FieldInfo)me.Member).GetValue(target);
          case MemberTypes.Property:
            return Add(((PropertyInfo)me.Member).GetValue(target, null));
          default:
            throw new NotSupportedException();
        }
      case ExpressionType.Call:
        {
          MethodCallExpression mce = (MethodCallExpression)expr;
          object obj;
          if (mce.Object == null)
          {
            obj= mce.Method.Invoke(mce.Object, Walk(mce.Arguments));
          }
          else
          {
            obj= mce.Method.Invoke(Walk(mce.Object), Walk(mce.Arguments));
          }
          return Add(obj);
        }

      case ExpressionType.Convert:
        {
          UnaryExpression uex = expr as UnaryExpression;
          object obj = Walk(uex.Operand);
          if (obj as IConvertible == null)
          {
            return obj;
          }
          else
          {
            return Convert.ChangeType(obj, uex.Operand.Type);
          }
        }
      default:
        throw new NotSupportedException();
    }
  }
  public void Dispose()
  {
    Debug.WriteLine($"Com Count:{m_Coms.Count}");

    for (int i = m_Coms.Count - 1; i >= 0; i--)
    {
      Marshal.ReleaseComObject(m_Coms[i]);
      //Debug.WriteLine("Released:" + m_Coms[i]);
    }
    m_Coms.Clear();
    for (int i = m_NetObjs.Count - 1; i >= 0; i--)
    {
      m_NetObjs[i].Dispose();
    }
    m_NetObjs.Clear();
  }
}

  

标签:释放,return,expr,mce,Walk,Add,obj,辅助,COM
来源: https://www.cnblogs.com/otoboku/p/16200331.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有