NativeObjectCache.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Linq;
  5. namespace Helper
  6. {
  7. public static class NativeObjectCache
  8. {
  9. private static object _lock = new object();
  10. private static Dictionary<Type, Dictionary<IntPtr, WeakReference>> _objectCache = new Dictionary<Type, Dictionary<IntPtr, WeakReference>>();
  11. public static void AddObject<T>(IntPtr nativePtr, T obj) where T : class
  12. {
  13. lock (_lock)
  14. {
  15. Dictionary<IntPtr, WeakReference> objCache = null;
  16. if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
  17. {
  18. objCache = new Dictionary<IntPtr, WeakReference>();
  19. _objectCache[typeof(T)] = objCache;
  20. }
  21. objCache[nativePtr] = new WeakReference(obj);
  22. }
  23. }
  24. public static void Flush()
  25. {
  26. lock(_lock)
  27. {
  28. foreach (var byType in _objectCache.ToArray())
  29. {
  30. foreach(var kvp in byType.Value.ToArray())
  31. {
  32. IDisposable disp = kvp.Value.Target as IDisposable;
  33. if(disp != null)
  34. {
  35. disp.Dispose();
  36. }
  37. }
  38. }
  39. }
  40. }
  41. public static void RemoveObject<T>(IntPtr nativePtr)
  42. {
  43. lock (_lock)
  44. {
  45. Dictionary<IntPtr, WeakReference> objCache = null;
  46. if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
  47. {
  48. objCache = new Dictionary<IntPtr, WeakReference>();
  49. _objectCache[typeof(T)] = objCache;
  50. }
  51. if (objCache.ContainsKey(nativePtr))
  52. {
  53. objCache.Remove(nativePtr);
  54. }
  55. }
  56. }
  57. public static T GetObject<T>(IntPtr nativePtr) where T : class
  58. {
  59. lock (_lock)
  60. {
  61. Dictionary<IntPtr, WeakReference> objCache = null;
  62. if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
  63. {
  64. objCache = new Dictionary<IntPtr, WeakReference>();
  65. _objectCache[typeof(T)] = objCache;
  66. }
  67. WeakReference reference = null;
  68. if (objCache.TryGetValue(nativePtr, out reference))
  69. {
  70. if (reference != null)
  71. {
  72. T obj = reference.Target as T;
  73. if (obj != null)
  74. {
  75. return (T)obj;
  76. }
  77. }
  78. }
  79. return null;
  80. }
  81. }
  82. public static T CreateOrGetObject<T>(IntPtr nativePtr, Func<System.IntPtr,T> create) where T : class
  83. {
  84. T outputValue = null;
  85. lock (_lock)
  86. {
  87. Dictionary<IntPtr, WeakReference> objCache = null;
  88. if (!_objectCache.TryGetValue(typeof(T), out objCache) || objCache == null)
  89. {
  90. objCache = new Dictionary<IntPtr, WeakReference>();
  91. _objectCache[typeof(T)] = objCache;
  92. }
  93. WeakReference reference = null;
  94. if (objCache.TryGetValue(nativePtr, out reference))
  95. {
  96. if ((reference != null) && reference.IsAlive)
  97. {
  98. outputValue = reference.Target as T;
  99. }
  100. }
  101. if (outputValue == null)
  102. {
  103. if (create != null)
  104. {
  105. outputValue = create(nativePtr);
  106. objCache[nativePtr] = new WeakReference(outputValue);
  107. }
  108. else if(typeof(T) == typeof(System.Object))
  109. {
  110. //T is an object, so lets just pass back our IntPtr, which is an object.
  111. outputValue = (T)(System.Object)nativePtr;
  112. }
  113. }
  114. }
  115. return outputValue;
  116. }
  117. }
  118. }