//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using TouchSocket.Resources; namespace TouchSocket.Core { /// /// 消息通知类。内部全为弱引用。 /// public class AppMessenger { private static AppMessenger m_instance; private readonly ReaderWriterLockSlim m_lockSlim = new ReaderWriterLockSlim(); private readonly Dictionary> m_tokenAndInstance = new Dictionary>(); /// /// 默认单例实例 /// public static AppMessenger Default { get { if (m_instance != null) { return m_instance; } lock (typeof(AppMessenger)) { if (m_instance != null) { return m_instance; } m_instance = new AppMessenger(); return m_instance; } } } /// /// 允许多广播注册 /// public bool AllowMultiple { get; set; } /// /// 添加 /// /// /// /// public void Add(string token, MessageInstance messageInstance) { using (WriteLock writeLock = new WriteLock(m_lockSlim)) { if (m_tokenAndInstance.ContainsKey(token)) { if (!AllowMultiple) { throw new MessageRegisteredException(TouchSocketStatus.TokenExisted.GetDescription(token)); } m_tokenAndInstance[token].Add(messageInstance); } else { m_tokenAndInstance.Add(token, new List() { messageInstance }); } } } /// /// 判断能否触发该消息,意味着该消息是否已经注册。 /// /// /// public bool CanSendMessage(string token) { using (ReadLock readLock = new ReadLock(m_lockSlim)) { return m_tokenAndInstance.ContainsKey(token); } } /// /// 清除所有消息 /// public void Clear() { using (WriteLock writeLock = new WriteLock(m_lockSlim)) { m_tokenAndInstance.Clear(); } } /// /// 获取所有消息 /// /// public string[] GetAllMessage() { using (ReadLock readLock = new ReadLock(m_lockSlim)) { return m_tokenAndInstance.Keys.ToArray(); } } /// /// 移除 /// /// public void Remove(string token) { using (WriteLock writeLock = new WriteLock(m_lockSlim)) { m_tokenAndInstance.Remove(token); } } /// /// 按对象移除 /// /// public void Remove(IMessageObject messageObject) { using (WriteLock writeLock = new WriteLock(m_lockSlim)) { List key = new List(); foreach (var item in m_tokenAndInstance.Keys) { foreach (var item2 in m_tokenAndInstance[item].ToArray()) { if (messageObject == item2.MessageObject) { m_tokenAndInstance[item].Remove(item2); if (m_tokenAndInstance[item].Count == 0) { key.Add(item); } } } } foreach (var item in key) { m_tokenAndInstance.Remove(item); } } } /// /// 发送消息 /// /// /// /// public Task SendAsync(string token, params object[] parameters) { return EasyTask.Run(() => { using (ReadLock readLock = new ReadLock(m_lockSlim)) { if (m_tokenAndInstance.TryGetValue(token, out List list)) { List clear = new List(); foreach (var item in list) { if (!item.Static && !item.WeakReference.TryGetTarget(out _)) { clear.Add(item); continue; } try { item.Invoke(item.MessageObject, parameters); } catch { } } foreach (var item in clear) { list.Remove(item); } } else { throw new MessageNotFoundException(TouchSocketStatus.MessageNotFound.GetDescription(token)); } } }); } /// /// 发送消息,当多播时,只返回最后一个返回值 /// /// 返回值类型 /// /// /// /// public Task SendAsync(string token, params object[] parameters) { return EasyTask.Run(() => { using (ReadLock readLock = new ReadLock(m_lockSlim)) { if (m_tokenAndInstance.TryGetValue(token, out List list)) { T result = default; List clear = new List(); for (int i = 0; i < list.Count; i++) { var item = list[i]; if (!item.Static && !item.WeakReference.TryGetTarget(out _)) { clear.Add(item); continue; } try { if (i == list.Count - 1) { result = (T)item.Invoke(item.MessageObject, parameters); } else { item.Invoke(item.MessageObject, parameters); } } catch { } } foreach (var item in clear) { list.Remove(item); } return result; } else { throw new MessageNotFoundException(TouchSocketStatus.MessageNotFound.GetDescription(token)); } } }); } } }