Selaa lähdekoodia

Improve RecipeEdit Performance
Improve RecipeEdit - Append or Copy Step Performance

git-svn-id: http://10.4.3.168:50001/svn/Furnace@121 dbcde07d-dcf5-c148-8a84-ac3097b7778e

Taizixuan 1 kuukausi sitten
vanhempi
commit
b489369756

+ 71 - 163
FrameworkLocal/UIClient/CenterViews/Editors/Recipe/RecipeDataBase.cs

@@ -18,6 +18,12 @@ using System.Xml;
 using System.ComponentModel;
 using OpenSEMI.ClientBase;
 using MECF.Framework.UI.Client.ClientBase;
+using System.Threading.Tasks;
+using System.Collections.Concurrent;
+using Mapster;
+using System.Diagnostics;
+using SciChart.Charting.Common.Extensions;
+using DocumentFormat.OpenXml.EMMA;
 
 namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
 {
@@ -331,155 +337,13 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
         public void CloneStep(ref Step destinationStep, Step originalStep)
         {
             int stepNo = destinationStep.StepNo;
-            destinationStep = (Step)CloneUtil.CloneObjectSetFlag(originalStep, "IsSaved", true);
-            destinationStep.StepNo = stepNo;
-            SetDelegateEvent(destinationStep);
-            ////destinationStep.StepNo = originalStep.StepNo;
-            //destinationStep.Name = originalStep.Name;
-            //destinationStep.Time = originalStep.Time;
-            //destinationStep.SkipWait = originalStep.SkipWait;
-            //destinationStep.EndBy = originalStep.EndBy;
-            //destinationStep.MFCSets = originalStep.MFCSets;
-            //destinationStep.MFMSets = originalStep.MFMSets;
-            //destinationStep.ValveSets = originalStep.ValveSets;
-
-            ////destinationStep.AlarmActionSets = originalStep.AlarmActionSets;
-            //foreach (var temkey in originalStep.AlarmActionSets.Keys)
-            //{
-            //    if (!destinationStep.AlarmActionSets.ContainsKey(temkey))
-            //    {
-            //        destinationStep.AlarmActionSets.Add(temkey, originalStep.AlarmActionSets[temkey]);
-            //    }
-            //    else
-            //    {
-            //        destinationStep.AlarmActionSets[temkey] = originalStep.AlarmActionSets[temkey];
-            //    }
-            //}
+            //destinationStep = (Step)CloneUtil.CloneObjectSetFlag(originalStep, "IsSaved", true);
 
-            //destinationStep.AlarmConditionTable = originalStep.AlarmConditionTable;
-            ////destinationStep.TemperatureSets = originalStep.TemperatureSets;
+            //TypeAdapterConfig<Param, Param>.NewConfig().MapToConstructor(true).Ignore(t=>t.IsSaved);
+            originalStep.Adapt(destinationStep);
 
-            //foreach (var temkey in originalStep.TemperatureSets.Keys)
-            //{
-            //    if (!destinationStep.TemperatureSets.ContainsKey(temkey))
-            //    {
-            //        destinationStep.TemperatureSets.Add(temkey, originalStep.TemperatureSets[temkey]);
-            //    }
-            //    else
-            //    {
-            //        destinationStep.TemperatureSets[temkey] = originalStep.TemperatureSets[temkey];
-            //    }
-            //}
-
-            //destinationStep.TemperatureControlMode = originalStep.TemperatureControlMode;
-            //destinationStep.TemperatureCorrect = originalStep.TemperatureCorrect;
-            //destinationStep.TemperaturePID = originalStep.TemperaturePID;
-            //destinationStep.LoaderCommand = originalStep.LoaderCommand;
-            //destinationStep.LoaderValue = originalStep.LoaderValue;
-            //destinationStep.PressCommand = originalStep.PressCommand;
-            //destinationStep.PressValue = originalStep.PressValue;
-            //destinationStep.TemperatureProfile = originalStep.TemperatureProfile;
-            //destinationStep.TemperatureAlarm = originalStep.TemperatureAlarm;
-
-            //destinationStep.CAPTemperatureAlarm = originalStep.CAPTemperatureAlarm;
-            //destinationStep.CAPSetValue = originalStep.CAPSetValue;
-            //destinationStep.CAPRampingValue = originalStep.CAPRampingValue;
-
-            //destinationStep.TemperatureStabilize = originalStep.TemperatureStabilize;
-            //destinationStep.TemperatureReadyCond = originalStep.TemperatureReadyCond;
-
-            //destinationStep.RFSwitch = originalStep.RFSwitch;
-            //destinationStep.RFSetpoint = originalStep.RFSetpoint;
-            //destinationStep.RFPowerSetpoint = originalStep.RFPowerSetpoint;
-            //destinationStep.C1Setpoint = originalStep.C1Setpoint;
-            //destinationStep.C2Setpoint = originalStep.C2Setpoint;
-            //destinationStep.ForwardPowerAlarmWatchTable = originalStep.ForwardPowerAlarmWatchTable;
-            //destinationStep.PrAlarmWatchTable = originalStep.PrAlarmWatchTable;
-            //destinationStep.PIAlarmWatchTable = originalStep.PIAlarmWatchTable;
-            //destinationStep.C1AlarmWatchTable = originalStep.C1AlarmWatchTable;
-            //destinationStep.C2AlarmWatchTable = originalStep.C2AlarmWatchTable;
-            //destinationStep.VppAlarmWatchTable = originalStep.VppAlarmWatchTable;
-            //destinationStep.VdcAlarmWatchTable = originalStep.VdcAlarmWatchTable;
-            ////destinationStep.Command = originalStep.Command;
-            ////destinationStep.APC_SetPressure = originalStep.APC_SetPressure;
-            ////destinationStep.EXOUSets = originalStep.EXOUSets;
-            ////destinationStep.ExternalSensor = originalStep.ExternalSensor;
-            ////destinationStep.GasLineN2_Flow = originalStep.GasLineN2_Flow;
-            ////destinationStep.GasLineN3_Flow = originalStep.GasLineN3_Flow;
-            ////destinationStep.IsnoneConditionCheck = originalStep.IsnoneConditionCheck;
-            ////destinationStep.ZAxisPosition = originalStep.ZAxisPosition;
-            ////destinationStep.ZAxisSpeed = originalStep.ZAxisSpeed;
-            ////destinationStep.RotatePosition = originalStep.RotatePosition;
-            ////destinationStep.RotateSpeed = originalStep.RotateSpeed;
-            ////destinationStep.RotateInterval = originalStep.RotateInterval;
-            ////destinationStep.ReachPressureValue = originalStep.ReachPressureValue;
-            ////destinationStep.PressureStabilizeSelected = originalStep.PressureStabilizeSelected;
-            ////destinationStep.PressureSonserValue = originalStep.PressureSonserValue;
-            ////destinationStep.PressureValveAngle = originalStep.PressureValveAngle;
-            ////destinationStep.PressureSettingVG = originalStep.PressureSettingVG;
-            ////destinationStep.PressureAlarmTableNo = originalStep.PressureAlarmTableNo;
-            ////destinationStep.EventSetting = originalStep.EventSetting;
-            ////destinationStep.FinishAutoProfile = originalStep.FinishAutoProfile;
-            ////destinationStep.ReachTemp = originalStep.ReachTemp;
-            ////destinationStep.ReachPressure = originalStep.ReachPressure;
-            ////destinationStep.ReachPressureVG = originalStep.ReachPressureVG;
-            ////destinationStep.PressureStabilizeVG = originalStep.PressureStabilizeVG;
-            ////destinationStep.ReachTempValue = originalStep.ReachTempValue;
-            ////destinationStep.TempStabilizeSelected = originalStep.TempStabilizeSelected;
-
-        }
-
-        public void CloneStep(Step destinationStep, Step originalStep)
-        {
-            //destinationStep.StepNo = originalStep.StepNo;
-            //destinationStep.Name = originalStep.Name;
-            //destinationStep.EndBy = originalStep.EndBy;
-            //destinationStep.Time = originalStep.Time;
-            //destinationStep.SkipWait = originalStep.SkipWait;
-            //destinationStep.Command = originalStep.Command;
-            //destinationStep.APC_SetPressure = originalStep.APC_SetPressure;
-            //destinationStep.EXOUSets = originalStep.EXOUSets;
-            //destinationStep.ExternalSensor = originalStep.ExternalSensor;
-            //destinationStep.GasLineN2_Flow = originalStep.GasLineN2_Flow;
-            //destinationStep.GasLineN3_Flow = originalStep.GasLineN3_Flow;
-            //destinationStep.IsnoneConditionCheck = originalStep.IsnoneConditionCheck;
-            //destinationStep.ZAxisPosition = originalStep.ZAxisPosition;
-            //destinationStep.ZAxisSpeed = originalStep.ZAxisSpeed;
-            //destinationStep.RotatePosition = originalStep.RotatePosition;
-            //destinationStep.RotateSpeed = originalStep.RotateSpeed;
-            //destinationStep.RotateInterval = originalStep.RotateInterval;
-            //destinationStep.MFCSets = originalStep.MFCSets;
-            //destinationStep.MFMSets = originalStep.MFMSets;
-            //destinationStep.ValveSets = originalStep.ValveSets;
-            //destinationStep.ReachPressureValue = originalStep.ReachPressureValue;
-            //destinationStep.PressureStabilizeSelected = originalStep.PressureStabilizeSelected;
-            //destinationStep.PressureSonserValue = originalStep.PressureSonserValue;
-            //destinationStep.PressureValveAngle = originalStep.PressureValveAngle;
-            //destinationStep.PressureSettingVG = originalStep.PressureSettingVG;
-            //destinationStep.SlowVacuumValue = originalStep.SlowVacuumValue;
-
-            //destinationStep.PressureAlarmTableNo = originalStep.PressureAlarmTableNo;
-            //destinationStep.TemperatureCorrect = originalStep.TemperatureCorrect;
-            //destinationStep.TemperaturePID = originalStep.TemperaturePID;
-            //destinationStep.LoaderCommand = originalStep.LoaderCommand;
-            //destinationStep.LoaderValue = originalStep.LoaderValue;
-            //destinationStep.PressCommand = originalStep.PressCommand;
-            //destinationStep.PressValue = originalStep.PressValue;
-            //destinationStep.TemperatureSets = originalStep.TemperatureSets;
-            //destinationStep.EventSetting = originalStep.EventSetting;
-            //destinationStep.FinishAutoProfile = originalStep.FinishAutoProfile;
-            //destinationStep.ReachTemp = originalStep.ReachTemp;
-            //destinationStep.O2Density = originalStep.O2Density;
-            //destinationStep.ReachPressure = originalStep.ReachPressure;
-            //destinationStep.ReachPressureVG = originalStep.ReachPressureVG;
-            //destinationStep.PressureStabilizeVG = originalStep.PressureStabilizeVG;
-            //destinationStep.ReachTempValue = originalStep.ReachTempValue;
-            //destinationStep.O2DensityValue = originalStep.O2DensityValue;
-            //destinationStep.RotateDirection = originalStep.RotateDirection;
-            //destinationStep.TempStabilizeSelected = originalStep.TempStabilizeSelected;
-            destinationStep = (Step)CloneUtil.CloneObject(originalStep);
+            destinationStep.StepNo = stepNo;
             SetDelegateEvent(destinationStep);
-
         }
 
         public RecipeDataBase()
@@ -1400,10 +1264,32 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
 
         public void SetDelegateEvent(Step step)
         {
-            MFCSetsCollectionChanged(step);
-            TemperatureSetsCollectionChanged(step);
-            ValveSetsCollectionChanged(step);
-            AUXSetsCollectionChanged(step);
+            //MFCSetsCollectionChanged(step);
+            //TemperatureSetsCollectionChanged(step);
+            //ValveSetsCollectionChanged(step);
+            //AUXSetsCollectionChanged(step);
+
+            Task[] tasks = new Task[4];
+            tasks[0] = Task.Factory.StartNew(() =>
+            {
+                MFCSetsCollectionChanged(step);
+            });
+
+            tasks[1] = Task.Factory.StartNew(() =>
+            {
+                TemperatureSetsCollectionChanged(step);
+            });
+
+            tasks[2] = Task.Factory.StartNew(() =>
+            {
+                ValveSetsCollectionChanged(step);
+            });
+
+            tasks[3] = Task.Factory.StartNew(() =>
+            {
+                AUXSetsCollectionChanged(step);
+            });
+            Task.WaitAll(tasks);
         }
 
         private void MFCSetsCollectionChanged(Step step)
@@ -2476,21 +2362,43 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
             PopSettingSteps.Clear();
             StepTolerances.Clear();
             StepNos.Clear();
-            if (steps.Count != 0)
+
+            if (steps.Count == 0)
+                return;
+
+            ConcurrentDictionary<int, Step> cache = new ConcurrentDictionary<int, Step>();
+            Step step = this.CreateStep(steps[0]);
+            StepNos.Add(step.StepNo);
+            Steps.Add(step);
+
+            Parallel.For(1, steps.Count - 1, index =>
             {
-                Step step = this.CreateStep(steps[0]);
-                var query1 = (from XmlNode n in steps select n).ToList();
-                query1.RemoveAt(0);
-                var allSteps = query1.AsParallel().AsOrdered()
-                      .Select(x => this.CreateStep(Steps[0], x));
-                StepNos.Add(step.StepNo);
-                Steps.Add(step);
-                foreach (var item in allSteps)
-                {
-                    StepNos.Add(item.StepNo);
-                    Steps.Add(item);
-                }
+                Step tempStep = CreateStep(step, steps.Item(index));
+                cache[tempStep.StepNo] = tempStep;
+            });
+
+            foreach (var item in cache)
+            {
+                StepNos.Add(item.Key);
+                Steps.Add(item.Value);
             }
+
+            //if (steps.Count != 0)
+            //{
+            //    Step step = this.CreateStep(steps[0]);
+            //    var query1 = (from XmlNode n in steps select n).ToList();
+            //    query1.RemoveAt(0);
+            //    var allSteps = query1.AsParallel().AsOrdered()
+            //          .Select(x => this.CreateStep(Steps[0], x));
+            //    StepNos.Add(step.StepNo);
+            //    Steps.Add(step);
+            //    foreach (var item in allSteps)
+            //    {
+            //        StepNos.Add(item.StepNo);
+            //        Steps.Add(item);
+            //    }
+            //}
+
         }
 
         private void LoadConfigs(XmlNode configNode)

+ 1 - 1
FrameworkLocal/UIClient/RecipeEditorLib/RecipeModel/Params/Param.cs

@@ -11,7 +11,7 @@ using Caliburn.Micro.Core;
 
 namespace RecipeEditorLib.RecipeModel.Params
 {
-    public abstract class Param : PropertyChangedBase
+    public class Param : PropertyChangedBase
     {
         public Action<Param> Feedback { get; set; }
         public Func<Param, bool> Check { get; set; }

+ 7 - 0
FrameworkLocal/UIClient/UIClient.csproj

@@ -40,6 +40,12 @@
     <Reference Include="log4net">
       <HintPath>..\..\ThirdParty\dlls\log4net.dll</HintPath>
     </Reference>
+    <Reference Include="Mapster, Version=7.2.0.0, Culture=neutral, PublicKeyToken=2f39883af23c29a8, processorArchitecture=MSIL">
+      <HintPath>..\..\Furnace\packages\Mapster.7.2.0\lib\net45\Mapster.dll</HintPath>
+    </Reference>
+    <Reference Include="Mapster.Core, Version=1.2.0.0, Culture=neutral, PublicKeyToken=e64997d676a9c1d3, processorArchitecture=MSIL">
+      <HintPath>..\..\Furnace\packages\Mapster.Core.1.2.0\lib\net45\Mapster.Core.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.DwayneNeed">
       <HintPath>..\..\ThirdParty\dlls\Microsoft.DwayneNeed.dll</HintPath>
     </Reference>
@@ -948,6 +954,7 @@
     <None Include="app.config" />
     <None Include="Caliburn.Micro\Caliburn.snk" />
     <Fakes Include="Fakes\MECF.Framework.UI.Core.fakes" />
+    <None Include="packages.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>

+ 44 - 38
Furnace/FurnaceSimulator/App.config

@@ -1,31 +1,29 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <configSections>
-    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=1b44e1d426115821"/>
+    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" />
   </configSections>
   <startup>
-    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
+    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
   </startup>
 
 
   <log4net>
     <appender name="fileAppender" type="log4net.Appender.RollingFileAppender">
-      <param name="File" value="Logs\appLog"/>
-      <param name="AppendToFile" value="true"/>
-      <param name="RollingStyle" value="Date"/>
-      <param name="StaticLogFileName" value="false"/>
-      <datePattern value="yyyyMMdd'.txt'"/>
+      <param name="File" value="Logs\appLog" />
+      <param name="AppendToFile" value="true" />
+      <param name="RollingStyle" value="Date" />
+      <param name="StaticLogFileName" value="false" />
+      <datePattern value="yyyyMMdd'.txt'" />
       <layout type="log4net.Layout.PatternLayout,log4net">
-        <param name="ConversionPattern" value="[%t] %m%n"/>
-        <param name="Header" value="--------------------------------[Header Log]-----------------------------------------
-"/>
-        <param name="Footer" value="--------------------------------[Footer Log]-----------------------------------------
-"/>
+        <param name="ConversionPattern" value="[%t] %m%n" />
+        <param name="Header" value="--------------------------------[Header Log]----------------------------------------- " />
+        <param name="Footer" value="--------------------------------[Footer Log]----------------------------------------- " />
       </layout>
     </appender>
     <root>
-      <level value="ALL"/>
-      <appender-ref ref="fileAppender"/>
+      <level value="ALL" />
+      <appender-ref ref="fileAppender" />
     </root>
   </log4net>
 
@@ -37,67 +35,75 @@
     <bindings>
       <netTcpBinding>
         <binding name="Aitex_netTcpBinding" maxReceivedMessageSize="102400000" receiveTimeout="infinite">
-          <readerQuotas maxDepth="32" maxStringContentLength="1048576" maxArrayLength="16384000" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
+          <readerQuotas maxDepth="32" maxStringContentLength="1048576" maxArrayLength="16384000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
           <security mode="None">
-            <transport clientCredentialType="None"/>
-            <message clientCredentialType="None"/>
+            <transport clientCredentialType="None" />
+            <message clientCredentialType="None" />
           </security>
         </binding>
       </netTcpBinding>
     </bindings>
     <services>
 		<service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc1">
-		    <endpoint address="net.tcp://localhost:6701/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+		    <endpoint address="net.tcp://localhost:6701/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
 	    </service>
 		<service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc2">
-		    <endpoint address="net.tcp://localhost:6702/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+		    <endpoint address="net.tcp://localhost:6702/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
 	    </service>
     <service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc3">
-      <endpoint address="net.tcp://localhost:6703/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+      <endpoint address="net.tcp://localhost:6703/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
     </service>
       <service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc4">
-        <endpoint address="net.tcp://localhost:6704/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+        <endpoint address="net.tcp://localhost:6704/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
       </service>
       <service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc5">
-        <endpoint address="net.tcp://localhost:6705/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+        <endpoint address="net.tcp://localhost:6705/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
       </service>
       <service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc6">
-        <endpoint address="net.tcp://localhost:6706/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+        <endpoint address="net.tcp://localhost:6706/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
       </service>
       <service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc7">
-        <endpoint address="net.tcp://localhost:6707/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+        <endpoint address="net.tcp://localhost:6707/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
       </service>
       <service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc8">
-        <endpoint address="net.tcp://localhost:6708/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+        <endpoint address="net.tcp://localhost:6708/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
       </service>
       <service behaviorConfiguration="BasicBehavior" name="FurnaceSimulator.Instances.SimulatorPlc9">
-        <endpoint address="net.tcp://localhost:6709/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService"/>
+        <endpoint address="net.tcp://localhost:6709/SimulatorPlcService" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.PLC.IWcfPlcService" />
       </service>
     </services>
     <behaviors>
       <serviceBehaviors>
         <behavior name="BasicBehavior">
-          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
-          <serviceMetadata httpGetEnabled="false"/>
-          <serviceDebug includeExceptionDetailInFaults="true"/>
-          <serviceAuthorization impersonateCallerForAllOperations="false"/>
+          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
+          <serviceMetadata httpGetEnabled="false" />
+          <serviceDebug includeExceptionDetailInFaults="true" />
+          <serviceAuthorization impersonateCallerForAllOperations="false" />
         </behavior>
         <behavior name="SingleModeBehavior">
-          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
-          <serviceMetadata httpGetEnabled="false"/>
-          <serviceDebug includeExceptionDetailInFaults="true"/>
-          <serviceAuthorization impersonateCallerForAllOperations="false"/>
+          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
+          <serviceMetadata httpGetEnabled="false" />
+          <serviceDebug includeExceptionDetailInFaults="true" />
+          <serviceAuthorization impersonateCallerForAllOperations="false" />
         </behavior>
       </serviceBehaviors>
       <endpointBehaviors>
         <behavior name="EndpointBehavior">
-          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
+          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
         </behavior>
       </endpointBehaviors>
     </behaviors>
     <client>
-      <endpoint address="net.tcp://localhost:8771/QueryDataService/Simulator" behaviorConfiguration="EndpointBehavior" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.DataCenter.IQueryDataService" name="Client_IQueryDataService"/>
-      <endpoint address="net.tcp://localhost:8751/InvokeService/Simulator" behaviorConfiguration="EndpointBehavior" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.OperationCenter.IInvokeService" name="Client_IInvokeService"/>
+      <endpoint address="net.tcp://localhost:8771/QueryDataService/Simulator" behaviorConfiguration="EndpointBehavior" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.DataCenter.IQueryDataService" name="Client_IQueryDataService" />
+      <endpoint address="net.tcp://localhost:8751/InvokeService/Simulator" behaviorConfiguration="EndpointBehavior" binding="netTcpBinding" bindingConfiguration="Aitex_netTcpBinding" contract="MECF.Framework.Common.OperationCenter.IInvokeService" name="Client_IInvokeService" />
     </client>
   </system.serviceModel>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
 </configuration>

+ 3 - 0
Furnace/FurnaceUI/ClientApp.cs

@@ -3,6 +3,8 @@ using MECF.Framework.UI.Client.ClientBase;
 using System.Collections.Generic;
 using System.IO;
 using Aitex.Common.Util;
+using Mapster;
+using RecipeEditorLib.RecipeModel.Params;
 
 
 namespace FurnaceUI.Client
@@ -18,6 +20,7 @@ namespace FurnaceUI.Client
 
         protected override void OnInitialize()
         {
+            TypeAdapterConfig<Param, Param>.NewConfig().MapToConstructor(true).Ignore(t=>t.IsSaved);
             WaferMoveManager.Instance.ShowCooling = false;
             WaferMoveManager.Instance.ShowAligner = false;
 

+ 6 - 0
Furnace/FurnaceUI/FurnaceUI.csproj

@@ -61,6 +61,12 @@
     <Reference Include="log4net">
       <HintPath>..\..\ThirdParty\dlls\log4net.dll</HintPath>
     </Reference>
+    <Reference Include="Mapster, Version=7.2.0.0, Culture=neutral, PublicKeyToken=2f39883af23c29a8, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mapster.7.2.0\lib\net45\Mapster.dll</HintPath>
+    </Reference>
+    <Reference Include="Mapster.Core, Version=1.2.0.0, Culture=neutral, PublicKeyToken=e64997d676a9c1d3, processorArchitecture=MSIL">
+      <HintPath>..\packages\Mapster.Core.1.2.0\lib\net45\Mapster.Core.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.DwayneNeed">
       <HintPath>..\..\ThirdParty\dlls\Microsoft.DwayneNeed.dll</HintPath>
     </Reference>

+ 2 - 0
Furnace/FurnaceUI/packages.config

@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
+  <package id="Mapster" version="7.2.0" targetFramework="net452" />
+  <package id="Mapster.Core" version="1.2.0" targetFramework="net452" />
   <package id="OxyPlot.Core" version="2.1.0" targetFramework="net452" />
   <package id="OxyPlot.Wpf" version="2.1.0" targetFramework="net452" />
   <package id="OxyPlot.Wpf.Shared" version="2.1.0" targetFramework="net452" />