COM对象释放辅助类

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
  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();
  }
}

  

posted @   otoboku  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示