Browse Source

使用Event类实现wafer更改通知注册客户端,修复多个进程获取wafer数据异常:原来逻辑是获取到更改后就给RT通知获取完成取消更改标记,此逻辑在多进程中,不能保证数据更改更新到所有进程。

huangping 3 weeks ago
parent
commit
d28041d257

+ 5 - 0
FrameworkLocal/Common/Event/EventManager.cs

@@ -954,5 +954,10 @@ namespace Aitex.Core.RT.Event
                 }
             }
         }
+
+        public bool? UpdateWafers(IEnumerable<string> modules)
+        {
+           return _eventService?.UpDateWafers(modules);
+        }
     }
 }

+ 27 - 2
FrameworkLocal/Common/Event/EventService.cs

@@ -9,6 +9,7 @@ using Aitex.Core.Util;
 using Aitex.Core.WCF.Interface;
 using System.Collections.Concurrent;
 using MECF.Framework.Common.Event;
+using System.Threading.Tasks;
 
 namespace Aitex.Core.WCF
 {
@@ -23,6 +24,8 @@ namespace Aitex.Core.WCF
 
         public event Action<bool> OnLockAndUnlockEvent;
 
+        public event Func<IEnumerable<string>,bool?> OnUpdateWaferEvent;
+
         private int _counter;
         public EventService()
         {
@@ -129,10 +132,32 @@ namespace Aitex.Core.WCF
                     }
                 
                 }
+            }
+        }
 
-                
-
+        public bool? UpDateWafers(IEnumerable<string> modules)
+        {
+            var tasks = new List<Task<bool?>>();
+            foreach (var client in _callbackClientList)
+            {
+                tasks.Add(Task.Run(() =>
+                 {
+                     try
+                     {
+                         return client.Value.SendChangedWaferModule(modules);//客户端通过回调接受事件
+                     }
+                     catch (Exception ex)
+                     {
+                         LOG.Error(string.Format("给客户端{0}发送事件失败,客户端被删除.", client.Key), ex);
+                         _callbackClientList.TryRemove(client.Key, out IEventServiceCallback service);
+                         _isLockState.TryRemove(client.Key, out bool lockState);
+                         return null;
+                     }
+                 }));
             }
+            Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(400));
+            if (tasks.Any(r => r.Result == false)) return false;
+            return true;
         }
 
 

+ 2 - 0
FrameworkLocal/Common/Event/EventServiceCallback.cs

@@ -17,6 +17,7 @@ namespace Aitex.Core.WCF
 
         public event Action<bool> OnLockAndUnlockEvent;
 
+        public event Func<IEnumerable<string>,bool?> OnUpdateWaferEvent;//通知获取wafer更新数据
         public void SendEvent(EventItem ev)
         {
             if (FireEvent != null)
@@ -32,5 +33,6 @@ namespace Aitex.Core.WCF
                 OnLockAndUnlockEvent(isLock);
             }
         }
+        public bool? SendChangedWaferModule(IEnumerable<string> changedModule)=> OnUpdateWaferEvent?.Invoke(changedModule);
     }
 }

+ 11 - 4
FrameworkLocal/Common/Event/EventServiceClient.cs

@@ -18,7 +18,7 @@ namespace Aitex.Core.WCF
         public event Action<EventItem> OnEvent;
         public event Action OnDisconnectedWithRT;
         public event Action<bool> LockAndUnlockEvent;
-
+        public event Func<IEnumerable<string>,bool?> OnUpdateWaferEvent;
         public bool InProcess { get; set; }
 
         private IEventService _service;
@@ -38,6 +38,7 @@ namespace Aitex.Core.WCF
                     }
                     _service.OnEvent += _service_OnEvent;
                     _service.OnLockAndUnlockEvent += _service_OnLockAndUnlockEvent;
+                    _service.OnUpdateWaferEvent += _sevice_OnUpdateWaferEvent;
 
                 }
 
@@ -52,6 +53,8 @@ namespace Aitex.Core.WCF
                 LockAndUnlockEvent(obj);
             }
         }
+        private bool? _sevice_OnUpdateWaferEvent(IEnumerable<string> modules)=> OnUpdateWaferEvent?.Invoke(modules);   
+
 
         public bool IsConnectedWithRT
         {
@@ -171,11 +174,14 @@ namespace Aitex.Core.WCF
 
         public event Action<bool> OnLockAndUnlockEvent;
 
+        public event Func<IEnumerable<string>,bool?> OnUpdateWaferEvent;
+
         public EventServiceClient(EventServiceCallback callbackInstance)
             : base(new InstanceContext(callbackInstance), "Client_IEventService", "EventService")
         {
             callbackInstance.FireEvent += new Action<EventItem>(callbackInstance_FireEvent);
             callbackInstance.OnLockAndUnlockEvent += CallbackInstance_OnLockAndUnlockEvent;
+            callbackInstance.OnUpdateWaferEvent += CallbackInstance_OnUpdateWaferEvent;
         }
 
 
@@ -187,13 +193,14 @@ namespace Aitex.Core.WCF
             }
         }
 
-     void CallbackInstance_OnLockAndUnlockEvent(bool isLock)
-    {
-        if (OnLockAndUnlockEvent != null)
+        void CallbackInstance_OnLockAndUnlockEvent(bool isLock)
+        {
+            if (OnLockAndUnlockEvent != null)
             {
                 OnLockAndUnlockEvent(isLock);
             }
         }
+        bool? CallbackInstance_OnUpdateWaferEvent(IEnumerable<string> modules) => OnUpdateWaferEvent?.Invoke(modules);
 
         public bool Register(Guid id)
         {

+ 2 - 0
FrameworkLocal/Common/Event/IEventService.cs

@@ -14,6 +14,8 @@ namespace Aitex.Core.WCF.Interface
 
         event Action<bool> OnLockAndUnlockEvent;
 
+        event Func<IEnumerable<string>,bool?> OnUpdateWaferEvent;
+
         [OperationContract]
         bool Register(Guid id);
 

+ 3 - 0
FrameworkLocal/Common/Event/IEventServiceCallback.cs

@@ -16,5 +16,8 @@ namespace Aitex.Core.WCF.Interface
 
         [OperationContract(IsOneWay = true)]
         void SendLockEvent(bool IsLock);
+
+        [OperationContract]
+        bool? SendChangedWaferModule(IEnumerable<string> modules);
     }
 }

+ 8 - 16
FrameworkLocal/Common/SubstrateTrackings/WaferManager.cs

@@ -76,8 +76,14 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
         public bool Serialize()
         {
+            if (NeedUpdateModule.Any(r => r.Value))
+            {
+                var modules = NeedUpdateModule.Where(r => r.Value).Select(r => r.Key).ToList();
+                if (!(Singleton<EventManager>.Instance.UpdateWafers(modules) == false))
+                    NeedUpdateModule.Clear();
+            }
             if (!_needSerialize) return true;
-            _needSerialize = false;
+            _needSerialize = false;          
             try
             {
                 if (_locationWafers != null)
@@ -141,22 +147,8 @@ namespace MECF.Framework.Common.SubstrateTrackings
 
             //EV.Subscribe(new EventItem("Event", Event_STS_Unoccupied, "Substrate location state is Unoccupied."));
             //EV.Subscribe(new EventItem("Event", Event_STS_Occupied, "Substrate location state is occupied."));
-
-            DATA.Subscribe("System.ChangeWafers", () => NeedUpdateModule);
-            OP.Subscribe("System.UpdateWafersNotify", (string cmd, object[] args) =>
-            {
-                if (args.Length > 0 && args[0] is Dictionary<string, bool> updateModules)
-                {
-                    foreach (var module in updateModules.Keys)
-                    {
-                        if (NeedUpdateModule.ContainsKey(module)) NeedUpdateModule[module] = false;
-                    }
-                    return true;
-                }
-                return false;
-            });
             Deserialize();
-            _thread = new PeriodicJob(1000, Serialize, $"SerializeMonitorHandler", true);
+            _thread = new PeriodicJob(500, Serialize, $"SerializeMonitorHandler", true);
         }
 
         public void SubscribeLocation(string module, int slotNumber)

+ 75 - 66
FrameworkLocal/UIClient/ClientBase/ModuleDataMonitor.cs

@@ -7,6 +7,7 @@ using System.Windows;
 using System.Windows.Threading;
 using Aitex.Core.RT.Log;
 using Aitex.Core.Util;
+using Aitex.Core.WCF;
 using DocumentFormat.OpenXml.Drawing.Charts;
 using MECF.Framework.Common.DataCenter;
 using MECF.Framework.Common.OperationCenter;
@@ -28,98 +29,106 @@ namespace MECF.Framework.UI.Client.ClientBase
             {
                 if (!string.IsNullOrEmpty(moduleInfo.Value.WaferDataName))
                 {
-                    _lstWaferDataName.Add(moduleInfo.Value.WaferDataName);
+                    _lstWaferDataName.Add(moduleInfo.Key);
                     _mapWaferDataModule[moduleInfo.Value.WaferDataName] = moduleInfo.Value;
                 }
             }
-
-            _monitorThread = new PeriodicJob(500, OnTimer, "Monitor Module Data Thread", true);
+            EventClient.Instance.OnUpdateWaferEvent += OnTimer;
+            OnTimer(_lstWaferDataName);//刚开始全部获取一遍
+            //_monitorThread = new PeriodicJob(500, OnTimer, "Monitor Module Data Thread", true);
         }
 
-        private bool OnTimer()
+        private bool? OnTimer(IEnumerable<string> modules)
         {
             try
             {
-                Dictionary<string, object> data = new Dictionary<string, object>();
-                var enableUpdateWafersNotify = (bool)QueryDataClient.Instance.Service.GetConfig("System.EnableUpdateWafersNotify");
-                if (enableUpdateWafersNotify)
+                //Dictionary<string, object> data = new Dictionary<string, object>();
+                //var enableUpdateWafersNotify = (bool)QueryDataClient.Instance.Service.GetConfig("System.EnableUpdateWafersNotify");
+                //if (enableUpdateWafersNotify)
+                //{
+                //    var changeModule = QueryDataClient.Instance.Service.GetData("System.ChangeWafers");
+                //    if (changeModule is Dictionary<string, bool> module && module?.Count > 0)
+                //    {
+                //        var changedModule = module.Where(r => r.Value);
+                //        if (!changedModule.Any()) return true;
+                //        InvokeClient.Instance.Service.DoOperation("System.UpdateWafersNotify", changeModule);
+                //        data = QueryDataClient.Instance.Service.PollData(changedModule.Select(r => $"{r.Key}.ModuleWaferList"));
+
+                //    }
+
+                //}
+                //else
+                //{
+                //    data = QueryDataClient.Instance.Service.PollData(_lstWaferDataName);
+                //}
+                if (modules?.Any() == true)
                 {
-                    var changeModule = QueryDataClient.Instance.Service.GetData("System.ChangeWafers");
-                    if (changeModule is Dictionary<string, bool> module && module?.Count > 0)
+                    var changedModule = modules.Where(r => _mapWaferDataModule.ContainsKey(r + ".ModuleWaferList"));
+                    if (!changedModule.Any()) return null;
+                    Dictionary<string, object> data = QueryDataClient.Instance.Service.PollData(changedModule.Select(r => $"{r}.ModuleWaferList"));
+                    if (data != null && Application.Current != null)
                     {
-                        var changedModule = module.Where(r => r.Value);
-                        if (!changedModule.Any()) return true;
-                        InvokeClient.Instance.Service.DoOperation("System.UpdateWafersNotify", changeModule);
-                        data = QueryDataClient.Instance.Service.PollData(changedModule.Select(r => $"{r.Key}.ModuleWaferList"));
-
-                    }
-                  
-                }
-                else
-                {
-                    data = QueryDataClient.Instance.Service.PollData(_lstWaferDataName);
-                }
-                if (data != null && Application.Current != null)
-                {
-                    Application.Current.Dispatcher.Invoke(new Action(() =>
-                    {
-                        foreach (var waferData in data)
+                        Application.Current.Dispatcher.Invoke(new Action(() =>
                         {
-                            if (!_mapWaferDataModule.ContainsKey(waferData.Key))
-                                continue;
+                            foreach (var waferData in data)
+                            {
+                                if (!_mapWaferDataModule.ContainsKey(waferData.Key))
+                                    continue;
 
-                            RTDefine.WaferInfo[] wafers = waferData.Value as RTDefine.WaferInfo[];
-                            if (wafers == null)
-                                continue;
+                                RTDefine.WaferInfo[] wafers = waferData.Value as RTDefine.WaferInfo[];
+                                if (wafers == null)
+                                    continue;
 
-                            ModuleInfo info = _mapWaferDataModule[waferData.Key];
-                            if (info.WaferManager.Wafers.Count == 0)
-                            {
-                                for (int i = 0; i < wafers.Length; i++)
+                                ModuleInfo info = _mapWaferDataModule[waferData.Key];
+                                if (info.WaferManager.Wafers.Count == 0)
                                 {
-                                    info.WaferManager.Wafers.Add(WaferInfoConverter(wafers[i], info.WaferModuleID, i));
-                                }
+                                    for (int i = 0; i < wafers.Length; i++)
+                                    {
+                                        info.WaferManager.Wafers.Add(WaferInfoConverter(wafers[i], info.WaferModuleID, i));
+                                    }
 
-                                if (info.IsWaferReverseDisplay)
-                                {
-                                    info.WaferManager.Wafers = new ObservableCollection<WaferInfo>(info.WaferManager.Wafers.Reverse());
+                                    if (info.IsWaferReverseDisplay)
+                                    {
+                                        info.WaferManager.Wafers = new ObservableCollection<WaferInfo>(info.WaferManager.Wafers.Reverse());
+                                    }
+                                    continue;
                                 }
-                                continue;
-                            }
 
-                            if (wafers.Length == info.WaferManager.Wafers.Count)
-                            {
-                                int index;
-                                for (int i = 0; i < wafers.Length; i++)
+                                if (wafers.Length == info.WaferManager.Wafers.Count)
                                 {
-                                    if (info.IsWaferReverseDisplay)
-                                        index = wafers.Length - i - 1;
-                                    else
-                                        index = i;
-
-                                    var convertedWafer = WaferInfoConverter(wafers[index], info.WaferModuleID, index);
-                                    info.WaferManager.Wafers[i].WaferStatus = convertedWafer.WaferStatus;
-                                    info.WaferManager.Wafers[i].WaferID = convertedWafer.WaferID;
-                                    info.WaferManager.Wafers[i].SourceName = convertedWafer.SourceName;
-                                    info.WaferManager.Wafers[i].WaferType = convertedWafer.WaferType;
-                                    info.WaferManager.Wafers[i].UseCount = convertedWafer.UseCount;
-                                    info.WaferManager.Wafers[i].UseTime = convertedWafer.UseTime;
-                                    info.WaferManager.Wafers[i].UseThick = convertedWafer.UseThick;
-                                    info.WaferManager.Wafers[i].Thick = convertedWafer.Thick;
-                                    info.WaferManager.Wafers[i].LotId = convertedWafer.LotId;
-                                    info.WaferManager.Wafers[i].ProcessJobID = convertedWafer.ProcessJobID;
+                                    int index;
+                                    for (int i = 0; i < wafers.Length; i++)
+                                    {
+                                        if (info.IsWaferReverseDisplay)
+                                            index = wafers.Length - i - 1;
+                                        else
+                                            index = i;
+
+                                        var convertedWafer = WaferInfoConverter(wafers[index], info.WaferModuleID, index);
+                                        info.WaferManager.Wafers[i].WaferStatus = convertedWafer.WaferStatus;
+                                        info.WaferManager.Wafers[i].WaferID = convertedWafer.WaferID;
+                                        info.WaferManager.Wafers[i].SourceName = convertedWafer.SourceName;
+                                        info.WaferManager.Wafers[i].WaferType = convertedWafer.WaferType;
+                                        info.WaferManager.Wafers[i].UseCount = convertedWafer.UseCount;
+                                        info.WaferManager.Wafers[i].UseTime = convertedWafer.UseTime;
+                                        info.WaferManager.Wafers[i].UseThick = convertedWafer.UseThick;
+                                        info.WaferManager.Wafers[i].Thick = convertedWafer.Thick;
+                                        info.WaferManager.Wafers[i].LotId = convertedWafer.LotId;
+                                        info.WaferManager.Wafers[i].ProcessJobID = convertedWafer.ProcessJobID;
+                                    }
                                 }
                             }
-                        }
-                    }));
+                        }));
+                    }
+                    return true;
                 }
+                return null;
             }
             catch (Exception ex)
             {
                 LOG.Error(ex.Message);
+                return false;
             }
-
-            return true;
         }