Fix bug where multiple threads modify same variable at the same time. Perform some refactoring

This commit is contained in:
Duc
2025-03-13 14:40:58 -07:00
parent ffa9905494
commit 492cbb9cd9
10 changed files with 84 additions and 102 deletions

View File

@@ -72,8 +72,8 @@ namespace ProgramLib
ProgramLib.Program.Instance().GetGuiManager()[ProgramGuiManager.WINDOWS.LIVE_DATA].Hide();
});
Program.Instance()._eventManager[EventManager.Events.UUT_POWER_ON].Reset();
Program.Instance()._eventManager[EventManager.Events.UUT_POWER_OFF].Set();
Program.Instance().EventManager[EventManager.Events.UUT_POWER_ON].Reset();
Program.Instance().EventManager[EventManager.Events.UUT_POWER_OFF].Set();
Program.Instance()._isUutPwrOn = false;
}
@@ -110,7 +110,7 @@ namespace ProgramLib
if (_sttoSuccess)
{
Program.Instance()._powerSupplySharedData.ResetAll();
Program.Instance().PowerSupplySharedData.ResetAll();
ProgramLib.Program.Instance().GetGuiManager()[ProgramGuiManager.WINDOWS.IMPEDANCE_CHECK].Dispatcher.Invoke((Action)delegate
{
@@ -122,8 +122,8 @@ namespace ProgramLib
// disable front panel
Program.Instance().MalMeasurementLibManager.PowerSupplyMeasurementManager.DisplayDisable("STE_POWER_SUPPLY_SYSTEM");
Program.Instance()._eventManager[EventManager.Events.UUT_POWER_OFF].Reset();
Program.Instance()._eventManager[EventManager.Events.UUT_POWER_ON].Set();
Program.Instance().EventManager[EventManager.Events.UUT_POWER_OFF].Reset();
Program.Instance().EventManager[EventManager.Events.UUT_POWER_ON].Set();
Program.Instance()._isUutPwrOn = true;
}
@@ -178,9 +178,9 @@ namespace ProgramLib
impedanceDataModel.PassFailImagePath = impedanceCheckWindow.ViewModel.ImageToResourcePathDict[passFailImage];
impedanceDataModel.Description = $"{measurementName} Measured {measurement} Range [0,50]";
if (Program.Instance()._testStandSeqContext != null)
if (Program.Instance().TestStandSeqContext != null)
{
Program.Instance()._testStandSeqContext.Step.AdditionalResults.CustomResults.Insert($"\"{measurementName}\"", $"\"Measured: {measurement++} Range [0,50] - {measurementStatus}\"");
Program.Instance().TestStandSeqContext.Step.AdditionalResults.CustomResults.Insert($"\"{measurementName}\"", $"\"Measured: {measurement++} Range [0,50] - {measurementStatus}\"");
}
impedanceCheckWindow.ViewModel.AddData(impedanceDataModel);

View File

@@ -1,28 +1,23 @@
using Raytheon.Instruments.PowerSupply;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProgramLib
{
{
/// <summary>
/// Stores voltage and current reading
/// </summary>
internal class PowerSupplyData
{
public double _voltage;
public double _current;
public PowerSupplyModuleInfo _powerSupplyModuleInfo;
public bool _initialized;
public double Voltage { get; set; }
public double Current { get; set; }
public PowerSupplyModuleInfo PowerSupplyModuleInfo { get; set; }
public bool Initialized { get; set; }
/// <summary>
/// Set data to unitialized
/// </summary>
public void Reset()
{
_initialized = false;
Initialized = false;
}
}
}

View File

@@ -1,9 +1,5 @@
using Raytheon.Instruments.PowerSupply;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using Raytheon.Instruments.PowerSupply;
namespace ProgramLib
{
@@ -27,20 +23,17 @@ namespace ProgramLib
{
// create a mutex for each module
syncObjDict[moduleName] = new object();
_powerSupplyDataDict[moduleName] = new PowerSupplyData();
}
}
lock (syncObjDict[moduleName])
{
if (!_powerSupplyDataDict.ContainsKey(moduleName))
{
_powerSupplyDataDict[moduleName] = new PowerSupplyData();
}
_powerSupplyDataDict[moduleName]._voltage = voltage;
_powerSupplyDataDict[moduleName]._current = current;
_powerSupplyDataDict[moduleName]._initialized = true;
_powerSupplyDataDict[moduleName]._powerSupplyModuleInfo = powerSupplyModuleInfo;
_powerSupplyDataDict[moduleName].Voltage = voltage;
_powerSupplyDataDict[moduleName].Current = current;
_powerSupplyDataDict[moduleName].Initialized = true;
_powerSupplyDataDict[moduleName].PowerSupplyModuleInfo = powerSupplyModuleInfo;
}
}
@@ -55,6 +48,8 @@ namespace ProgramLib
{
// create a mutex for each module
syncObjDict[moduleName] = new object();
_powerSupplyDataDict[moduleName] = new PowerSupplyData();
}
}

View File

@@ -109,9 +109,9 @@ namespace ProgramLib
impedanceDataModel.PassFailImagePath = impedanceCheckWindow.ViewModel.ImageToResourcePathDict[passFailImage];
impedanceDataModel.Description = $"{measurement.Value._cableAndPinId} Measured {testResult.ToString("0.00")} Range [{measurement.Value._lowerLimit},{measurement.Value._upperLimit}]";
if (Program.Instance()._testStandSeqContext != null)
if (Program.Instance().TestStandSeqContext != null)
{
Program.Instance()._testStandSeqContext.Step.AdditionalResults.CustomResults.Insert($"\"{measurement.Value._cableAndPinId}\"", $"\"Measured: {testResult.ToString("0.00")} Range [{measurement.Value._lowerLimit},{measurement.Value._upperLimit}] - {measurementStatus}\"");
Program.Instance().TestStandSeqContext.Step.AdditionalResults.CustomResults.Insert($"\"{measurement.Value._cableAndPinId}\"", $"\"Measured: {testResult.ToString("0.00")} Range [{measurement.Value._lowerLimit},{measurement.Value._upperLimit}] - {measurementStatus}\"");
}
impedanceCheckWindow.ViewModel.AddData(impedanceDataModel);
@@ -158,7 +158,7 @@ namespace ProgramLib
const string RELAY_EXCLUSION_SECTION_NAME = $"{MAIN_SECTION_NAME}.RELAY_EXCLUSION_LIST";
const string EXCLUSION_LIST_KEY = "EXCLUSION_LIST";
ConfigurationFile configurationFile = new ConfigurationFile(Program.Instance()._testMethodConfigFilePath);
ConfigurationFile configurationFile = new ConfigurationFile(Program.Instance().TestMethodConfigFilePath);
const char COMMA_DELIM = ',';

View File

@@ -15,21 +15,11 @@ GOVERNMENT.
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
-------------------------------------------------------------------------*/
using Raytheon;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Raytheon.Instruments;
using Raytheon.Common;
using NLog;
using System.Windows.Interop;
using ProgramLib;
using NationalInstruments.TestStand.Interop.API;
using System.Runtime.ExceptionServices;
using MeasurementManagerLib;
using Raytheon.Instruments;
namespace ProgramLib
{
@@ -41,7 +31,7 @@ namespace ProgramLib
private ProgramGuiManager _guiManager = null;
internal bool _isUutPwrOn = false;
internal PowerSupplySharedData _powerSupplySharedData = new PowerSupplySharedData();
internal PowerSupplySharedData PowerSupplySharedData { get; set; }
/// <summary>
/// Initialize power supply measurement manager
@@ -52,6 +42,7 @@ namespace ProgramLib
{
try
{
PowerSupplySharedData = new PowerSupplySharedData();
MalMeasurementLibManager.InitializePowerSupplyMeasurementManager();
}
catch (Exception ex)

View File

@@ -61,13 +61,13 @@ namespace ProgramLib
#endregion
internal SequenceContext _testStandSeqContext;
internal UutInfo _uutInfo;
internal EventManager _eventManager = new EventManager();
internal FileAndFolderManager _fileAndFolderManager;
internal IConfigurationFile _programConfig { get; private set; }
internal SequenceContext TestStandSeqContext { get; private set; }
internal UutInfo UutInfo { get; private set; }
internal EventManager EventManager { get; private set; }
internal FileAndFolderManager FileAndFolderManager { get; set; }
internal IConfigurationFile ProgramConfig { get; private set; }
internal MalMeasurementLibManager MalMeasurementLibManager { get; private set; }
internal string _testMethodConfigFilePath;
internal string TestMethodConfigFilePath { get; private set; }
internal bool SttoSuccess { get; set; }
@@ -99,7 +99,7 @@ namespace ProgramLib
if (_program != null)
{
// signal to all running threads to exit
_program._eventManager[EventManager.Events.GLOBAL_QUIT].Set();
_program.EventManager[EventManager.Events.GLOBAL_QUIT].Set();
UutPowerAction uutPowerAction = new UutPowerAction();
uutPowerAction.UutPowerOff();
@@ -133,15 +133,16 @@ namespace ProgramLib
_logger = LogManager.GetCurrentClassLogger();
string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
_programConfig = new ConfigurationFile(Path.Combine(assemblyFolder, GeneralConstants.ProgramConfigFilename));
ProgramConfig = new ConfigurationFile(Path.Combine(assemblyFolder, GeneralConstants.ProgramConfigFilename));
_testMethodConfigFilePath = Path.Combine(assemblyFolder, GeneralConstants.TestMethodConfigFolderName, GeneralConstants.TestMethodConfigFileName);
TestMethodConfigFilePath = Path.Combine(assemblyFolder, GeneralConstants.TestMethodConfigFolderName, GeneralConstants.TestMethodConfigFileName);
_fileAndFolderManager = new FileAndFolderManager(_programConfig);
EventManager = new EventManager();
FileAndFolderManager = new FileAndFolderManager(ProgramConfig);
if (testStandSeqContext != null)
{
_testStandSeqContext = testStandSeqContext as SequenceContext;
TestStandSeqContext = testStandSeqContext as SequenceContext;
}
// make sure PN/SN are valid (TS may not pass in the PN)
@@ -162,7 +163,7 @@ namespace ProgramLib
SttoSuccess = false;
// Initialze all other configuration that the program needs
_uutInfo = new UutInfo(_partNumber, _serialNumber);
UutInfo = new UutInfo(_partNumber, _serialNumber);
try
{
@@ -185,19 +186,19 @@ namespace ProgramLib
{
_logger?.Debug($"Entering {this.GetType().Name}::{System.Reflection.MethodBase.GetCurrentMethod().Name}() ...");
if (_testStandSeqContext != null)
if (TestStandSeqContext != null)
{
// clear any setting that we have added for any steps in the Setup Group
for (int i = 0; i < _testStandSeqContext.Sequence.GetNumSteps(StepGroups.StepGroup_Setup); i++)
for (int i = 0; i < TestStandSeqContext.Sequence.GetNumSteps(StepGroups.StepGroup_Setup); i++)
{
_testStandSeqContext.Sequence.GetStep(i, StepGroups.StepGroup_Setup).PostExpression = "";
TestStandSeqContext.Sequence.GetStep(i, StepGroups.StepGroup_Setup).PostExpression = "";
}
// clear any setting that we have added for any steps in the Main Group
for (int i = 0; i < _testStandSeqContext.Sequence.GetNumSteps(StepGroups.StepGroup_Main); i++)
for (int i = 0; i < TestStandSeqContext.Sequence.GetNumSteps(StepGroups.StepGroup_Main); i++)
{
_testStandSeqContext.Sequence.GetStep(i, StepGroups.StepGroup_Main).PostExpression = "";
_testStandSeqContext.Sequence.GetStep(i, StepGroups.StepGroup_Main).AdditionalResults.CustomResults.Clear();
TestStandSeqContext.Sequence.GetStep(i, StepGroups.StepGroup_Main).PostExpression = "";
TestStandSeqContext.Sequence.GetStep(i, StepGroups.StepGroup_Main).AdditionalResults.CustomResults.Clear();
}
}
}
@@ -221,7 +222,7 @@ namespace ProgramLib
/// <returns></returns>
private void TerminateTestOnMainThreadError(Exception ex)
{
if (_testStandSeqContext != null)
if (TestStandSeqContext != null)
{
_logger.Error(ex.Message + "\n" + ex.StackTrace);
@@ -230,13 +231,13 @@ namespace ProgramLib
if (!_terminateTestInitiated)
{
// tells teststand there's a exception occurred and give it the error message
_testStandSeqContext.Step.PostExpression = $"Step.Result.Error.Msg=\"{ex.Message} \", Step.Result.Error.Occurred=True";
TestStandSeqContext.Step.PostExpression = $"Step.Result.Error.Msg=\"{ex.Message} \", Step.Result.Error.Occurred=True";
_testStandSeqContext.Step.ResultStatus = "Error";
TestStandSeqContext.Step.ResultStatus = "Error";
// tells TestStand to go to clean up
_testStandSeqContext.StepGroup = StepGroups.StepGroup_Cleanup;
_testStandSeqContext.NextStepIndex = 0;
TestStandSeqContext.StepGroup = StepGroups.StepGroup_Cleanup;
TestStandSeqContext.NextStepIndex = 0;
_terminateTestInitiated = true;
}
@@ -255,19 +256,19 @@ namespace ProgramLib
/// <returns></returns>
internal void TerminateTestOnSupportThreadError()
{
if (_testStandSeqContext != null)
if (TestStandSeqContext != null)
{
lock (_terminateTestSyncObj)
{
if (!_terminateTestInitiated)
{
// tells teststand there's a exception occurred and give it the error message
_testStandSeqContext.SequenceErrorMessage = _fatalErrorMsgFromSupportThread + " ";
_testStandSeqContext.SequenceErrorOccurred = true;
TestStandSeqContext.SequenceErrorMessage = _fatalErrorMsgFromSupportThread + " ";
TestStandSeqContext.SequenceErrorOccurred = true;
// tells TestStand to go to clean up
_testStandSeqContext.StepGroup = StepGroups.StepGroup_Cleanup;
_testStandSeqContext.NextStepIndex = 0;
TestStandSeqContext.StepGroup = StepGroups.StepGroup_Cleanup;
TestStandSeqContext.NextStepIndex = 0;
_terminateTestInitiated = true;
}

View File

@@ -65,8 +65,8 @@ namespace ProgramLib
try
{
Dictionary<Events, EventWaitHandle> eventDict = new Dictionary<Events, EventWaitHandle>();
eventDict[Events.GLOBAL_QUIT] = Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.FATAL_FAILURE] = Program.Instance()._eventManager[EventManager.Events.FATAL_FAILURE];
eventDict[Events.GLOBAL_QUIT] = Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.FATAL_FAILURE] = Program.Instance().EventManager[EventManager.Events.FATAL_FAILURE];
eventDict[Events.EVENT_TIMED_OUT] = null;
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
@@ -75,7 +75,7 @@ namespace ProgramLib
if (id == Events.FATAL_FAILURE)
{
Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT].Set();
Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT].Set();
UutPowerAction uutPowerAction = new UutPowerAction();
uutPowerAction.UutPowerOff();

View File

@@ -79,8 +79,8 @@ namespace ProgramLib
try
{
Dictionary<Events, EventWaitHandle> eventDict = new Dictionary<Events, EventWaitHandle>();
eventDict[Events.GLOBAL_QUIT] = Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_ON] = Program.Instance()._eventManager[EventManager.Events.UUT_POWER_ON];
eventDict[Events.GLOBAL_QUIT] = Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_ON] = Program.Instance().EventManager[EventManager.Events.UUT_POWER_ON];
eventDict[Events.EVENT_TIMED_OUT] = null;
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
@@ -119,8 +119,8 @@ namespace ProgramLib
try
{
Dictionary<Events, EventWaitHandle> eventDict = new Dictionary<Events, EventWaitHandle>();
eventDict[Events.GLOBAL_QUIT] = Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_OFF] = Program.Instance()._eventManager[EventManager.Events.UUT_POWER_OFF];
eventDict[Events.GLOBAL_QUIT] = Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_OFF] = Program.Instance().EventManager[EventManager.Events.UUT_POWER_OFF];
eventDict[Events.EVENT_TIMED_OUT] = null;
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);

View File

@@ -76,8 +76,8 @@ namespace ProgramLib
try
{
Dictionary<Events, EventWaitHandle> eventDict = new Dictionary<Events, EventWaitHandle>();
eventDict[Events.GLOBAL_QUIT] = Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_ON] = Program.Instance()._eventManager[EventManager.Events.UUT_POWER_ON];
eventDict[Events.GLOBAL_QUIT] = Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_ON] = Program.Instance().EventManager[EventManager.Events.UUT_POWER_ON];
eventDict[Events.EVENT_TIMED_OUT] = null;
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
@@ -119,8 +119,8 @@ namespace ProgramLib
try
{
Dictionary<Events, EventWaitHandle> eventDict = new Dictionary<Events, EventWaitHandle>();
eventDict[Events.GLOBAL_QUIT] = Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_OFF] = Program.Instance()._eventManager[EventManager.Events.UUT_POWER_OFF];
eventDict[Events.GLOBAL_QUIT] = Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_OFF] = Program.Instance().EventManager[EventManager.Events.UUT_POWER_OFF];
eventDict[Events.EVENT_TIMED_OUT] = null;
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
@@ -142,7 +142,7 @@ namespace ProgramLib
if (!ovpTriggeredInPowerSupply && !ocpTriggeredInPowerSupply)
{
Program.Instance()._powerSupplySharedData.SetData(moduleName, data.Voltage, data.Current, _powerSupplyModuleInfoDict[moduleName]);
Program.Instance().PowerSupplySharedData.SetData(moduleName, data.Voltage, data.Current, _powerSupplyModuleInfoDict[moduleName]);
}
else
{
@@ -225,10 +225,10 @@ namespace ProgramLib
/// <returns></returns>
private void HandleOutOfToleranceCondition(string errorMsg)
{
if (!Program.Instance()._eventManager[EventManager.Events.FATAL_FAILURE].WaitOne(0))
if (!Program.Instance().EventManager[EventManager.Events.FATAL_FAILURE].WaitOne(0))
{
Program.Instance().SetFatalErrorMsgFromSupportThread(errorMsg);
Program.Instance()._eventManager[EventManager.Events.FATAL_FAILURE].Set();
Program.Instance().EventManager[EventManager.Events.FATAL_FAILURE].Set();
}
}

View File

@@ -80,8 +80,8 @@ namespace ProgramLib
try
{
Dictionary<Events, EventWaitHandle> eventDict = new Dictionary<Events, EventWaitHandle>();
eventDict[Events.GLOBAL_QUIT] = Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_ON] = Program.Instance()._eventManager[EventManager.Events.UUT_POWER_ON];
eventDict[Events.GLOBAL_QUIT] = Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_ON] = Program.Instance().EventManager[EventManager.Events.UUT_POWER_ON];
eventDict[Events.EVENT_TIMED_OUT] = null;
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
@@ -120,8 +120,8 @@ namespace ProgramLib
try
{
Dictionary<Events, EventWaitHandle> eventDict = new Dictionary<Events, EventWaitHandle>();
eventDict[Events.GLOBAL_QUIT] = Program.Instance()._eventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_OFF] = Program.Instance()._eventManager[EventManager.Events.UUT_POWER_OFF];
eventDict[Events.GLOBAL_QUIT] = Program.Instance().EventManager[EventManager.Events.GLOBAL_QUIT];
eventDict[Events.UUT_POWER_OFF] = Program.Instance().EventManager[EventManager.Events.UUT_POWER_OFF];
eventDict[Events.EVENT_TIMED_OUT] = null;
EventGroup<Events, EventWaitHandle> eventGroup = new EventGroup<Events, EventWaitHandle>(eventDict);
@@ -132,17 +132,17 @@ namespace ProgramLib
if (id == Events.EVENT_TIMED_OUT)
{
PowerSupplyData data = Program.Instance()._powerSupplySharedData.GetData("STE_PVM_5V");
PowerSupplyData data = Program.Instance().PowerSupplySharedData.GetData("STE_PVM_5V");
if (data != null && data._initialized)
if (data != null && data.Initialized)
{
_powerModuleToPowerDataModelDict["UUT_P20V"].ActualVoltage = data._voltage.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_P20V"].ExpectedVoltage = data._powerSupplyModuleInfo.voltageSetpoint_.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_P20V"].ActualCurrent = data._current.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_P20V"].ActualVoltage = data.Voltage.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_P20V"].ExpectedVoltage = data.PowerSupplyModuleInfo.voltageSetpoint_.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_P20V"].ActualCurrent = data.Current.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_N20V"].ActualVoltage = data._voltage.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_N20V"].ExpectedVoltage = data._powerSupplyModuleInfo.voltageSetpoint_.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_N20V"].ActualCurrent = data._current.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_N20V"].ActualVoltage = data.Voltage.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_N20V"].ExpectedVoltage = data.PowerSupplyModuleInfo.voltageSetpoint_.ToString("0.00");
_powerModuleToPowerDataModelDict["UUT_N20V"].ActualCurrent = data.Current.ToString("0.00");
}
}
else