其他分享
首页 > 其他分享> > COM对象释放辅助类

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