MulticastPrsnt.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. namespace Uestc.Auto6.Dso.Core
  7. {
  8. public abstract class MulticastPrsnt<V> : IDisposable, IBroadcaster
  9. where V : IView
  10. {
  11. private protected abstract INotifyPropertyChanged? Model
  12. {
  13. get;
  14. }
  15. private readonly List<V> _Views = new();
  16. public IEnumerable<V> GetViewList()
  17. {
  18. return _Views.ToList();
  19. }
  20. public Boolean TryAddView(V vu)
  21. {
  22. Boolean res = false;
  23. lock ((_Views as ICollection).SyncRoot)
  24. {
  25. if (!_Views.Contains(vu))
  26. {
  27. _Views.Add(vu);
  28. res = true;
  29. }
  30. }
  31. return res;
  32. }
  33. public void AddViewList(IEnumerable<V> vuList)
  34. {
  35. lock ((_Views as ICollection).SyncRoot)
  36. {
  37. foreach (var vu in vuList)
  38. {
  39. if (!_Views.Contains(vu))
  40. {
  41. _Views.Add(vu);
  42. }
  43. }
  44. }
  45. }
  46. public Boolean TryRemoveView(V vu)
  47. {
  48. Boolean res = false;
  49. lock ((_Views as ICollection).SyncRoot)
  50. {
  51. var idx = _Views.IndexOf(vu);
  52. if (idx >= 0)
  53. {
  54. _Views.RemoveAt(idx);
  55. res = true;
  56. }
  57. }
  58. return res;
  59. }
  60. public void RemoveViewList(IEnumerable<V> vuList)
  61. {
  62. lock ((_Views as ICollection).SyncRoot)
  63. {
  64. foreach (var vu in vuList)
  65. {
  66. var idx = _Views.IndexOf(vu);
  67. if (idx >= 0)
  68. {
  69. _Views.RemoveAt(idx);
  70. }
  71. }
  72. }
  73. }
  74. public Boolean FrozenVu
  75. {
  76. get;
  77. set;
  78. } = false;
  79. public event EventHandler<CustomEventArg>? PublisherChanged;
  80. protected void OnRaiseCustomEvent(CustomEventArg e)
  81. {
  82. PublisherChanged?.Invoke(this, e);
  83. }
  84. protected internal void OnPropertyChanged(Object? sender, PropertyChangedEventArgs e)
  85. {
  86. OnRaiseCustomEvent(new CustomEventArg(e.PropertyName ?? ""));
  87. if (!FrozenVu)
  88. {
  89. lock ((_Views as ICollection).SyncRoot)
  90. {
  91. //foreach (var vu in GetViewList())
  92. try
  93. {
  94. foreach (var vu in _Views)
  95. {
  96. vu.UpdateView(this, e.PropertyName ?? "");
  97. }
  98. }
  99. catch
  100. {
  101. throw;
  102. }
  103. }
  104. }
  105. }
  106. #region Dispose
  107. private Boolean _Disposed = false;
  108. public void Dispose()
  109. {
  110. Dispose(true);
  111. //标记gc不在调用析构函数
  112. GC.SuppressFinalize(this);
  113. }
  114. ~MulticastPrsnt()
  115. {
  116. Dispose(false);
  117. }
  118. private protected virtual void Dispose(Boolean disposing)
  119. {
  120. //如果已经被回收,就中断执行
  121. if (_Disposed)
  122. {
  123. return;
  124. }
  125. if (disposing)
  126. {
  127. //TODO:释放本对象中管理的托管资源
  128. _Views.Clear();
  129. var m = Model;
  130. if (m != null)
  131. {
  132. m.PropertyChanged -= OnPropertyChanged;
  133. }
  134. }
  135. //TODO:释放非托管资源
  136. _Disposed = true;
  137. }
  138. #endregion
  139. }
  140. }