- aggiunto pulsante di test Refresh
- implementato ExecProcessManager che gestisce il lancio di piu' esecuzioni contemporaneament - corretta gestione scrittura backup lista porte - correzione costruttori Door e JsonDoor con aggiunta nState
This commit is contained in:
@@ -31,6 +31,9 @@
|
||||
<Button Content="Produce All"
|
||||
ToolTip="Send all to production"
|
||||
Command="{Binding ProduceAll_Command}"/>
|
||||
<Button Content="Refresh"
|
||||
ToolTip="Send all to production"
|
||||
Command="{Binding Refresh_Command}"/>
|
||||
</StackPanel>
|
||||
<DataGrid Grid.Row="1"
|
||||
ItemsSource="{Binding DoorList}"
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
Imports System.Collections.ObjectModel
|
||||
Imports System.IO
|
||||
Imports Newtonsoft.Json
|
||||
Imports Newtonsoft.Json.Converters
|
||||
Imports System.Windows.Threading
|
||||
Imports Newtonsoft.Json.Linq
|
||||
Imports Supervisor.Plugin.Interface
|
||||
Imports System.Text.RegularExpressions
|
||||
|
||||
Public Class DoorListPageVM
|
||||
Inherits VMBase
|
||||
|
||||
Private m_BackupTimer As New DispatcherTimer
|
||||
Private m_RefreshGraphicsTimer As New DispatcherTimer
|
||||
Private m_ExecProcessManager As ExecProcessManager
|
||||
|
||||
Private m_DoorList As New ObservableCollection(Of Door)
|
||||
Public ReadOnly Property DoorList As ObservableCollection(Of Door)
|
||||
@@ -40,7 +40,7 @@ Public Class DoorListPageVM
|
||||
Private m_cmdDeleteAll As ICommand
|
||||
Private m_cmdProduce As ICommand
|
||||
Private m_cmdProduceAll As ICommand
|
||||
|
||||
Private m_cmdRefresh As ICommand
|
||||
|
||||
#Region "CONSTRUCTOR"
|
||||
|
||||
@@ -50,8 +50,12 @@ Public Class DoorListPageVM
|
||||
GetPluginPrivateProfileString(S_GENERAL, "BackupDir", "", sBackupDirPath)
|
||||
Dim sBackupFilePath As String = sBackupDirPath & "\Backup.json"
|
||||
Read(sBackupFilePath)
|
||||
m_BackupTimer.Interval = New TimeSpan(1000)
|
||||
m_BackupTimer.Interval = New TimeSpan(0, 0, 1)
|
||||
AddHandler m_BackupTimer.Tick, AddressOf BackupTimer_Tick
|
||||
m_RefreshGraphicsTimer.Interval = New TimeSpan(0, 0, 1)
|
||||
AddHandler m_RefreshGraphicsTimer.Tick, AddressOf RefreshGraphicsTimer_Tick
|
||||
m_BackupTimer.Start()
|
||||
m_RefreshGraphicsTimer.Start()
|
||||
End Sub
|
||||
#End Region ' CONSTRUCTOR
|
||||
|
||||
@@ -77,7 +81,6 @@ Public Class DoorListPageVM
|
||||
|
||||
m_DoorList = New ObservableCollection(Of Door)((From JsonDoor In JsonDoorList
|
||||
Select New Door(JsonDoor)).ToList())
|
||||
'NotifyPropertyChanged(NameOf(DoorList))
|
||||
End Sub
|
||||
|
||||
Public Sub Write(FilePath As String)
|
||||
@@ -117,13 +120,6 @@ Public Class DoorListPageVM
|
||||
|
||||
Friend Sub WriteBackup()
|
||||
m_nModifyIndex += 1
|
||||
If m_bWritingBackup Then Return
|
||||
m_bWritingBackup = True
|
||||
Dim sBackupDirPath As String = ""
|
||||
GetPluginPrivateProfileString(S_GENERAL, "BackupDir", "", sBackupDirPath)
|
||||
Dim sBackupFilePath As String = sBackupDirPath & "\Backup.json"
|
||||
Write(sBackupFilePath)
|
||||
m_bWritingBackup = False
|
||||
End Sub
|
||||
|
||||
Private Sub BackupTimer_Tick(sender As Object, e As EventArgs)
|
||||
@@ -132,6 +128,21 @@ Public Class DoorListPageVM
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Sub RefreshGraphicsTimer_Tick(sender As Object, e As EventArgs)
|
||||
If IsNothing(m_ExecProcessManager) Then Return
|
||||
' ciclo su coda risultati
|
||||
Dim ArgumentsResult As ProcessArgsResult = m_ExecProcessManager.ArgumentsResultDequeue
|
||||
While Not IsNothing(ArgumentsResult)
|
||||
' aggiorno risultatao sulla porta
|
||||
Dim CurrRequestDoor As Door = m_DoorList.FirstOrDefault(Function(x) x.nId = ArgumentsResult.ProcessArgs.nId)
|
||||
If Not IsNothing(CurrRequestDoor) Then
|
||||
CurrRequestDoor.SetState(If(ArgumentsResult.nResult = 0, Door.DoorStates.VERIFIED, Door.DoorStates.VERIFICATION_FAILED))
|
||||
End If
|
||||
WriteBackup()
|
||||
ArgumentsResult = m_ExecProcessManager.ArgumentsResultDequeue
|
||||
End While
|
||||
End Sub
|
||||
|
||||
Friend Function GetNextDoor() As Door
|
||||
Return m_DoorList.FirstOrDefault(Function(x) x.nState >= Door.DoorStates.SENT_TO_PRODUCTION AndAlso x.nState <= Door.DoorStates.IN_PRODUCTION)
|
||||
End Function
|
||||
@@ -152,31 +163,6 @@ Public Class DoorListPageVM
|
||||
End Property
|
||||
|
||||
Public Sub OpenCSV()
|
||||
'' test lancio esecuzione programma
|
||||
'Dim sCamExePath As String = ""
|
||||
'GetPluginPrivateProfileString(S_GENERAL, "CAMExePath", "", sCamExePath)
|
||||
'Dim sMainLuaPath As String = ""
|
||||
'GetPluginPrivateProfileString(S_GENERAL, "MainLUA", "", sMainLuaPath)
|
||||
'Dim sDDFDirPath As String = ""
|
||||
'GetPluginPrivateProfileString(S_GENERAL, "DDFDir", "", sDDFDirPath)
|
||||
'Dim sDDFFilePath As String = sDDFDirPath & "\both_machines.ddf"
|
||||
'Dim Proc As New Process()
|
||||
'Proc.StartInfo.FileName = sCamExePath
|
||||
'Proc.StartInfo.RedirectStandardInput = False
|
||||
'Proc.StartInfo.RedirectStandardOutput = False
|
||||
'Proc.StartInfo.Arguments = 1.ToString() & " """ & sMainLuaPath & """ """ & sDDFFilePath & """" ' & """ ""1"""
|
||||
''Proc.StartInfo.Arguments = """" & sDDFFilePath & """" & " ""2"""
|
||||
'Proc.StartInfo.UseShellExecute = False
|
||||
'Proc.StartInfo.CreateNoWindow = True
|
||||
'If Proc.Start Then
|
||||
' While Not Proc.HasExited
|
||||
' Dim x = 3
|
||||
' Threading.Thread.Sleep(100)
|
||||
' End While
|
||||
'End If
|
||||
'Map.refSupervisorFunction.PlgOutLog("Prova di funzionamento riferimento funzioni host da Plugin!!")
|
||||
|
||||
|
||||
Dim sDir As String = String.Empty
|
||||
'GetMainPrivateProfileString(S_GENERAL, K_LASTIMPDIR, "", sDir)
|
||||
Dim OpenFileDialog As New Microsoft.Win32.OpenFileDialog() With {
|
||||
@@ -272,15 +258,62 @@ Public Class DoorListPageVM
|
||||
MessageBox.Show("The following lines are not valid and have been skipped:" & sLineErrorList, "Error", MessageBoxButton.OK, MessageBoxImage.Error)
|
||||
End If
|
||||
End Using
|
||||
' verifico porte
|
||||
'For Each Door In m_DoorList
|
||||
' Dim bExecResult As Boolean = ExecCAMProcess(Door.sDDFName)
|
||||
' Door.SetState(If(bExecResult, Door.DoorStates.VERIFIED, Door.DoorStates.VERIFICATION_FAILED))
|
||||
'Next
|
||||
Dim sCamExePath As String = ""
|
||||
GetPluginPrivateProfileString(S_GENERAL, "CAMExePath", "", sCamExePath)
|
||||
Dim sMainLuaPath As String = ""
|
||||
GetPluginPrivateProfileString(S_GENERAL, "MainLUA", "", sMainLuaPath)
|
||||
Dim bStartExecProcessManager As Boolean = False
|
||||
If IsNothing(m_ExecProcessManager) Then
|
||||
bStartExecProcessManager = True
|
||||
m_ExecProcessManager = New ExecProcessManager(sCamExePath, """" & sMainLuaPath & """")
|
||||
'm_ExecProcessManager.SetPostProcess(AddressOf ExecProcessManager_PostProcess)
|
||||
AddHandler m_ExecProcessManager.m_AllArgsProcessed, AddressOf ExecProcessManager_AllArgsProcessed
|
||||
m_ExecProcessManager.SetMaxCamInstances(3)
|
||||
End If
|
||||
Dim sDDFDirPath As String = ""
|
||||
GetPluginPrivateProfileString(S_GENERAL, "DDFDir", "", sDDFDirPath)
|
||||
For Each Door In m_DoorList
|
||||
If Door.nState = Door.DoorStates.LOADED_FROM_CSV Then
|
||||
Dim sDDFFilePath As String = sDDFDirPath & "\" & Door.sDDFName
|
||||
m_ExecProcessManager.ArgumentsEnqueue(New ProcessArgs(Door.nId, sDDFFilePath))
|
||||
End If
|
||||
Next
|
||||
If bStartExecProcessManager OrElse m_ExecProcessManager.ExecutionThreadStatus = ExecProcessManager.ExecutionThreadStatuses.STOPPED Then
|
||||
m_ExecProcessManager.StartExecutionThread()
|
||||
End If
|
||||
End If
|
||||
WriteBackup()
|
||||
End Sub
|
||||
|
||||
Public Sub ExecProcessManager_AllArgsProcessed()
|
||||
m_ExecProcessManager.StopExecutionThread()
|
||||
End Sub
|
||||
|
||||
Public Sub ExecProcessManager_PostProcess(ProcessArgsResult As ProcessArgsResult)
|
||||
' verifico file di risultati
|
||||
Dim sDDFDirPath As String = ""
|
||||
GetPluginPrivateProfileString(S_GENERAL, "DDFDir", "", sDDFDirPath)
|
||||
Dim sDDFFilePath As String = sDDFDirPath & "\" & ProcessArgsResult.ProcessArgs.sArgs
|
||||
Dim sTxtFilePath As String = Path.ChangeExtension(sDDFDirPath, ".txt")
|
||||
If Not File.Exists(sTxtFilePath) Then
|
||||
ProcessArgsResult.SetResult(-1)
|
||||
Return
|
||||
End If
|
||||
Dim TxtFileLines As String() = File.ReadAllLines(sTxtFilePath)
|
||||
For nLineIndex As Integer = 0 To TxtFileLines.Count - 1
|
||||
Dim Match As Match = Regex.Match(TxtFileLines(nLineIndex), "\s*Err\s*=\s*(\d*)\s*")
|
||||
If Not IsNothing(Match) AndAlso Not IsNothing(Match.Groups(1)) Then
|
||||
Dim sResult As String = Match.Groups(1).Value
|
||||
Dim nResult As Integer = -2
|
||||
If Integer.TryParse(sResult, nResult) Then
|
||||
ProcessArgsResult.SetResult(nResult)
|
||||
Else
|
||||
ProcessArgsResult.SetResult(-2)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
#End Region ' OpenCSV
|
||||
|
||||
#Region "SkipDoor"
|
||||
@@ -435,6 +468,25 @@ Public Class DoorListPageVM
|
||||
|
||||
#End Region ' ProduceAll
|
||||
|
||||
#Region "Refresh"
|
||||
|
||||
Public ReadOnly Property Refresh_Command As ICommand
|
||||
Get
|
||||
If m_cmdRefresh Is Nothing Then
|
||||
m_cmdRefresh = New Command(AddressOf Refresh)
|
||||
End If
|
||||
Return m_cmdRefresh
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Sub Refresh()
|
||||
m_SelDoor.SetState(Door.DoorStates.SENT_TO_PRODUCTION)
|
||||
|
||||
'RefreshGraphicsTimer_Tick(Nothing, Nothing)
|
||||
End Sub
|
||||
|
||||
#End Region ' Refresh
|
||||
|
||||
#End Region ' COMMANDS
|
||||
|
||||
End Class
|
||||
@@ -518,16 +570,14 @@ Public Class Door
|
||||
End Property
|
||||
|
||||
Private m_nState As DoorStates = DoorStates.LOADED_FROM_CSV
|
||||
<JsonProperty>
|
||||
<JsonConverter(GetType(StringEnumConverter))>
|
||||
Public ReadOnly Property nState As DoorStates
|
||||
Get
|
||||
Return m_nState
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub SetState(value As DoorStates)
|
||||
Friend Sub SetState(value As DoorStates, Optional bUpdate As Boolean = True)
|
||||
m_nState = value
|
||||
NotifyPropertyChanged(NameOf(nState))
|
||||
If bUpdate Then NotifyPropertyChanged(NameOf(nState))
|
||||
End Sub
|
||||
|
||||
Sub New(nId As Integer, nCSVLine As Integer, sDDFName As String, sCSVName As String, nQuantity As Integer, dWidth As Double, dHeight As Double, dThickness As Double, HeaderList As String(), ValueList As String())
|
||||
@@ -555,6 +605,7 @@ Public Class Door
|
||||
m_dHeight = JsonDoor.dHeight
|
||||
m_dWidth = JsonDoor.dWidth
|
||||
m_dThickness = JsonDoor.dThickness
|
||||
m_nState = JsonDoor.nState
|
||||
m_CustomerParameters = JsonDoor.CustomerParameters
|
||||
End Sub
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="Utility\Command.vb" />
|
||||
<Compile Include="Utility\ExecProcessManager.vb" />
|
||||
<Compile Include="Utility\GenInterface.vb" />
|
||||
<Compile Include="Utility\IniFile.vb" />
|
||||
<Compile Include="Utility\JsonUtility.vb" />
|
||||
|
||||
@@ -0,0 +1,646 @@
|
||||
Imports System.IO
|
||||
Imports System.Threading
|
||||
Imports MS.Internal
|
||||
Imports Supervisor.Plugin.FiveLakes.ThreadData
|
||||
|
||||
Public Class ExecProcessManager
|
||||
|
||||
Public Event m_AllArgsProcessed()
|
||||
|
||||
Public Enum ExecutionThreadStatuses As Integer
|
||||
RUNNING = 1
|
||||
STOPPED = 2
|
||||
End Enum
|
||||
|
||||
' riferimento al thread principale
|
||||
Private m_ExecutionThread As Thread
|
||||
Private m_ExecutionThreadStatus As ExecutionThreadStatuses = ExecutionThreadStatuses.STOPPED
|
||||
Public ReadOnly Property ExecutionThreadStatus As ExecutionThreadStatuses
|
||||
Get
|
||||
Return m_ExecutionThreadStatus
|
||||
End Get
|
||||
End Property
|
||||
' array dei thread
|
||||
Private ThreadList As Thread()
|
||||
' array dei dati dei thread
|
||||
Private ThreadDataList As ThreadData()
|
||||
' variabile che ferma i processi
|
||||
Private m_bStopProcess As Boolean = False
|
||||
' variabile che conferma chiusura dei processi
|
||||
Private m_bExecutionThreadStoped As Boolean = False
|
||||
' numero massimo di istanze del cam
|
||||
Private m_MaxCamInstances As Integer = 1
|
||||
' nome dell'eseguibile da lanciare
|
||||
Private m_sProcessFileName As String = ""
|
||||
' stringa di argomenti dell'eseguibile da lanciare
|
||||
Private m_sProcessArguments As String = ""
|
||||
' coda delle cose da eseguire
|
||||
Private ArgumentsQueueLock As New Object
|
||||
Private m_ArgumentsQueue As New Queue(Of ProcessArgs)
|
||||
Public ReadOnly Property ArgumentsQueue As Queue(Of ProcessArgs)
|
||||
Get
|
||||
Return m_ArgumentsQueue
|
||||
End Get
|
||||
End Property
|
||||
' coda dei risultati
|
||||
Private ArgumentsResultQueueLock As New Object
|
||||
Private m_ArgumentsResultQueue As New Queue(Of ProcessArgsResult)
|
||||
Public ReadOnly Property ArgumentsResultQueue As Queue(Of ProcessArgsResult)
|
||||
Get
|
||||
Return m_ArgumentsResultQueue
|
||||
End Get
|
||||
End Property
|
||||
|
||||
' funzione che richiede prossimo elemento da processare
|
||||
Private m_delGetNextProcessArgs As Func(Of ProcessArgs)
|
||||
Public Sub SetGetNextProcessArgs(GetNextProcessArgs As Func(Of ProcessArgs))
|
||||
m_delGetNextProcessArgs = GetNextProcessArgs
|
||||
End Sub
|
||||
' funzione di pre processing dell'elemento
|
||||
Private m_delPreProcess As Func(Of ProcessArgs, ProcessArgs)
|
||||
Public Sub SetPreProcess(PreProcess As Func(Of ProcessArgs, ProcessArgs))
|
||||
m_delPreProcess = PreProcess
|
||||
End Sub
|
||||
' funzione di post processing dell'elemento
|
||||
Private m_delPostProcess As Action(Of ProcessArgsResult)
|
||||
Public Sub SetPostProcess(PostProcess As Action(Of ProcessArgsResult))
|
||||
m_delPostProcess = PostProcess
|
||||
End Sub
|
||||
|
||||
Sub New(sProcessFileName As String, sProcessArguments As String)
|
||||
m_sProcessFileName = sProcessFileName
|
||||
m_sProcessArguments = sProcessArguments
|
||||
End Sub
|
||||
|
||||
Public Function ArgumentsEnqueue(ProcessArgs As ProcessArgs) As Boolean
|
||||
If ProcessArgs.nId <= 0 OrElse String.IsNullOrWhiteSpace(ProcessArgs.sArgs) Then Return False
|
||||
SyncLock ArgumentsQueueLock
|
||||
m_ArgumentsQueue.Enqueue(ProcessArgs)
|
||||
End SyncLock
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Public Function ArgumentsDequeue() As ProcessArgs
|
||||
Dim DequeueProcessArgs As ProcessArgs = Nothing
|
||||
SyncLock ArgumentsQueueLock
|
||||
If m_ArgumentsQueue.Count > 0 Then
|
||||
DequeueProcessArgs = m_ArgumentsQueue.Dequeue()
|
||||
End If
|
||||
End SyncLock
|
||||
Return DequeueProcessArgs
|
||||
End Function
|
||||
|
||||
Public Function ArgumentsResultEnqueue(ProcessArgsResult As ProcessArgsResult) As Boolean
|
||||
SyncLock ArgumentsResultQueueLock
|
||||
m_ArgumentsResultQueue.Enqueue(ProcessArgsResult)
|
||||
End SyncLock
|
||||
Return True
|
||||
End Function
|
||||
|
||||
Public Function ArgumentsResultDequeue() As ProcessArgsResult
|
||||
Dim DequeueProcessArgsResult As ProcessArgsResult = Nothing
|
||||
SyncLock ArgumentsResultQueueLock
|
||||
If m_ArgumentsResultQueue.Count > 0 Then
|
||||
DequeueProcessArgsResult = m_ArgumentsResultQueue.Dequeue()
|
||||
End If
|
||||
End SyncLock
|
||||
Return DequeueProcessArgsResult
|
||||
End Function
|
||||
|
||||
Public Sub SetMaxCamInstances(nValue As Integer)
|
||||
' Numero di core logici da utilizzare (minimo tra presenti sul PC e imposti da INI)
|
||||
Dim nMaxThread As Integer = Math.Min(Environment.ProcessorCount, nValue)
|
||||
m_MaxCamInstances = nMaxThread
|
||||
End Sub
|
||||
|
||||
' funzione che avvia thread principale
|
||||
Public Sub StartExecutionThread()
|
||||
If m_ExecutionThreadStatus = ExecutionThreadStatuses.RUNNING Then Return
|
||||
m_bStopProcess = False
|
||||
m_bExecutionThreadStoped = False
|
||||
m_ExecutionThread = New Thread(Sub()
|
||||
ExecutionProcess()
|
||||
End Sub)
|
||||
|
||||
m_ExecutionThread.SetApartmentState(ApartmentState.STA)
|
||||
' avvio thread di gestione della macchina che avvia la connessione
|
||||
m_ExecutionThread.Start()
|
||||
|
||||
m_ExecutionThreadStatus = ExecutionThreadStatuses.RUNNING
|
||||
End Sub
|
||||
|
||||
Public Sub StopExecutionThread()
|
||||
If m_ExecutionThreadStatus = ExecutionThreadStatuses.STOPPED Then Return
|
||||
m_bStopProcess = True
|
||||
While Not m_bExecutionThreadStoped
|
||||
Thread.Sleep(100)
|
||||
End While
|
||||
If Not IsNothing(m_ExecutionThread) Then
|
||||
m_ExecutionThread.Abort()
|
||||
While Not m_ExecutionThread.ThreadState = ThreadState.Aborted
|
||||
Thread.Sleep(100)
|
||||
End While
|
||||
m_ExecutionThread = Nothing
|
||||
End If
|
||||
ThreadList = Nothing
|
||||
m_ExecutionThreadStatus = ExecutionThreadStatuses.STOPPED
|
||||
End Sub
|
||||
|
||||
' funzione di esecuzione del thread principale che gestice i processi
|
||||
Private Sub ExecutionProcess()
|
||||
Dim bStopMainProcess As Boolean = False
|
||||
Dim nStartingProc As Integer = 0
|
||||
While Not bStopMainProcess
|
||||
bStopMainProcess = m_bStopProcess
|
||||
' se processo fermato, fermo i thread
|
||||
If bStopMainProcess Then
|
||||
If Not IsNothing(ThreadList) AndAlso ThreadList.Count > 0 AndAlso Not IsNothing(ThreadList(0)) Then
|
||||
' li fermo
|
||||
m_bStopProcess = True
|
||||
' verifico siano terminati
|
||||
Dim bOneNotEnded As Boolean = True
|
||||
While bOneNotEnded
|
||||
bOneNotEnded = False
|
||||
For Each Thread In ThreadList
|
||||
If Not IsNothing(Thread) Then
|
||||
If Thread.IsAlive Then
|
||||
bOneNotEnded = True
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End While
|
||||
' pulisco la lista
|
||||
For ThreadIndex = 0 To ThreadList.Count - 1
|
||||
ThreadList(ThreadIndex) = Nothing
|
||||
Next
|
||||
m_bStopProcess = False
|
||||
End If
|
||||
m_bExecutionThreadStoped = True
|
||||
Return
|
||||
End If
|
||||
' se lista processi nulla o vuota, li faccio partire
|
||||
If (IsNothing(ThreadList) OrElse ThreadList.Count = 0) Then
|
||||
ThreadList = New Thread(m_MaxCamInstances - 1) {}
|
||||
ThreadDataList = New ThreadData(m_MaxCamInstances - 1) {}
|
||||
For nThreadIndex = 0 To m_MaxCamInstances - 1
|
||||
Dim ThreadId As Integer = nThreadIndex
|
||||
ThreadList(nThreadIndex) = New Thread(Sub()
|
||||
ThreadFunction(ThreadId)
|
||||
End Sub)
|
||||
ThreadList(nThreadIndex).SetApartmentState(ApartmentState.STA)
|
||||
' avvio thread di gestione della macchina che avvia la connessione
|
||||
ThreadList(nThreadIndex).Start()
|
||||
Thread.Sleep(100)
|
||||
Next
|
||||
End If
|
||||
' se qualche processo in stop, lo faccio ripartire
|
||||
For ThreadIndex = 0 To ThreadList.Count - 1
|
||||
If ThreadIndex < ThreadList.Count Then
|
||||
Dim Thread = ThreadList(ThreadIndex)
|
||||
If Not IsNothing(Thread) Then
|
||||
If Thread.ThreadState = ThreadState.Stopped OrElse
|
||||
Thread.ThreadState = ThreadState.Aborted OrElse
|
||||
Thread.ThreadState = ThreadState.Suspended OrElse
|
||||
(Not ThreadDataList(ThreadIndex).ProcessStatus = ProcessStatuses.TOBESTARTED AndAlso
|
||||
(IsNothing(ThreadDataList(ThreadIndex).Process) OrElse
|
||||
(Not IsNothing(ThreadDataList(ThreadIndex).Process) AndAlso ThreadDataList(ThreadIndex).Process.HasExited))) Then
|
||||
' inserire un ritardo di rilancio?
|
||||
' lo chiudo e rilancio
|
||||
'Thread.Sleep(500)
|
||||
Thread.Abort()
|
||||
Thread.Sleep(100)
|
||||
While Not Thread.ThreadState = ThreadState.Aborted
|
||||
Thread.Sleep(100)
|
||||
End While
|
||||
Thread = Nothing
|
||||
Dim ThreadId As Integer = ThreadIndex
|
||||
ThreadList(ThreadIndex) = New Thread(Sub()
|
||||
ThreadFunction(ThreadId)
|
||||
End Sub)
|
||||
ThreadList(ThreadIndex).SetApartmentState(ApartmentState.STA)
|
||||
' avvio thread di gestione della macchina che avvia la connessione
|
||||
ThreadList(ThreadIndex).Start()
|
||||
End If
|
||||
Else
|
||||
Dim ThreadId As Integer = ThreadIndex
|
||||
If ThreadIndex < ThreadList.Count Then
|
||||
ThreadList(ThreadIndex) = New Thread(Sub()
|
||||
ThreadFunction(ThreadId)
|
||||
End Sub)
|
||||
ThreadList(ThreadIndex).SetApartmentState(ApartmentState.STA)
|
||||
' avvio thread di gestione della macchina che avvia la connessione
|
||||
ThreadList(ThreadIndex).Start()
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
' verifico se coda vuota e tutti i processi hanno finito
|
||||
Dim nQueueArgs As Integer = 0
|
||||
SyncLock ArgumentsQueueLock
|
||||
nQueueArgs = m_ArgumentsQueue.Count
|
||||
End SyncLock
|
||||
If nQueueArgs = 0 Then
|
||||
Dim bProcessWaiting As Boolean = False
|
||||
For Each ThreadData In ThreadDataList
|
||||
If ThreadData.ProcessStatus = ProcessStatuses.WAITINGANSWER OrElse ThreadData.ProcessStatus = ProcessStatuses.ANSWERRECEIVED Then
|
||||
bProcessWaiting = True
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
If Not bProcessWaiting Then
|
||||
' creo thread per lanciare evento asincrono di fine calcolo
|
||||
Dim AllArgsProcessedThread = New Thread(Sub()
|
||||
RaiseEvent m_AllArgsProcessed()
|
||||
End Sub)
|
||||
AllArgsProcessedThread.SetApartmentState(ApartmentState.STA)
|
||||
AllArgsProcessedThread.Start()
|
||||
End If
|
||||
End If
|
||||
Thread.Sleep(1000)
|
||||
End While
|
||||
End Sub
|
||||
|
||||
' funzione di esecuzione del singolo processo che comunica con il programma
|
||||
Private Sub ThreadFunction(ThreadIndex As Integer)
|
||||
Dim MyThreadData As New ThreadData
|
||||
ThreadDataList(ThreadIndex) = MyThreadData
|
||||
'Dim CurrThreadStat As New ThreadStat(ThreadIndex, DateTime.Now)
|
||||
'HistoryThreadDataList.Add(CurrThreadStat)
|
||||
'MyThreadData.SetThreadStat(CurrThreadStat)
|
||||
'Dim sDrive As String = "c" ' If(ThreadIndex Mod 2 = 0, "A", "B")
|
||||
'Dim sCurrDdfDir As String = sDrive & ":\EgtData\WebDoor\Ddf"
|
||||
'Dim stopWatch As New Stopwatch()
|
||||
'Dim lExeTime As Long = 0
|
||||
'Dim lOtherTime As Long = 0
|
||||
|
||||
' avvio processo
|
||||
Dim Proc As Process = New Process()
|
||||
Proc.StartInfo.FileName = m_sProcessFileName
|
||||
Proc.StartInfo.RedirectStandardInput = True
|
||||
Proc.StartInfo.RedirectStandardOutput = True
|
||||
Proc.StartInfo.Arguments = ThreadIndex.ToString() & " " & m_sProcessArguments
|
||||
Proc.StartInfo.UseShellExecute = False
|
||||
Proc.StartInfo.CreateNoWindow = True
|
||||
AddHandler Proc.OutputDataReceived, AddressOf Thread_OutputDataReceived
|
||||
|
||||
If Proc.Start() Then
|
||||
'Dim CurrPocStat As New ProcStat(DateTime.Now)
|
||||
'CurrThreadStat.ProcExecutionList.Add(CurrPocStat)
|
||||
Proc.BeginOutputReadLine()
|
||||
MyThreadData.SetProcess(Proc)
|
||||
MyThreadData.SetProcessStatus(ProcessStatuses.NULL)
|
||||
|
||||
'Dim nProc0Wait As Integer = 0
|
||||
' ciclo per leggere coda ed eseguire
|
||||
While Not m_bStopProcess AndAlso Not Proc.HasExited
|
||||
Select Case MyThreadData.ProcessStatus
|
||||
Case ThreadData.ProcessStatuses.NULL
|
||||
'MyThreadData.SetThreadOperation(ThreadOperations.WaitingData)
|
||||
' se c'e' qualcosa da processare
|
||||
'Dim nNumTaskToProcess As Integer = 0
|
||||
'If ThreadIndex = 0 Then
|
||||
' nNumTaskToProcess = currWDC.numTask2proc
|
||||
' If nNumTaskToProcess > 0 Then
|
||||
' If Not m_bCheckOrder Then m_bCheckOrder = True
|
||||
' Else
|
||||
' If m_bCheckOrder Then m_bCheckOrder = False
|
||||
' Thread.Sleep(100)
|
||||
' End If
|
||||
'ElseIf m_bCheckOrder Then
|
||||
' nNumTaskToProcess = currWDC.numTask2proc
|
||||
' If nNumTaskToProcess = 0 Then
|
||||
' m_bCheckOrder = False
|
||||
' End If
|
||||
'End If
|
||||
Dim NextProcessArgs As ProcessArgs = Nothing
|
||||
If Not IsNothing(m_delGetNextProcessArgs) Then
|
||||
NextProcessArgs = m_delGetNextProcessArgs()
|
||||
Else
|
||||
NextProcessArgs = ArgumentsDequeue()
|
||||
End If
|
||||
|
||||
If Not IsNothing(NextProcessArgs) AndAlso NextProcessArgs.nId > 0 AndAlso Not String.IsNullOrWhiteSpace(NextProcessArgs.sArgs) Then
|
||||
If Not IsNothing(m_delPreProcess) Then
|
||||
NextProcessArgs = m_delPreProcess(NextProcessArgs)
|
||||
End If
|
||||
MyThreadData.SetCurrRequest(NextProcessArgs)
|
||||
Proc.StandardInput.WriteLine(ThreadIndex & "," & NextProcessArgs.sArgs)
|
||||
MyThreadData.SetProcessStatus(ThreadData.ProcessStatuses.WAITINGANSWER)
|
||||
End If
|
||||
'If m_bCheckOrder Then
|
||||
' Dim LastRequest As Dictionary(Of String, CalcReqtDTO) = currWDC.queueList(1)
|
||||
' If LastRequest.Count > 0 Then
|
||||
' MyThreadData.SetThreadOperation(ThreadOperations.FoundRequest)
|
||||
|
||||
' Dim ConvItem As KeyValuePair(Of String, String)
|
||||
' ConvItem = New KeyValuePair(Of String, String)(LastRequest.First().Key, LastRequest.First().Value.DDF)
|
||||
' MyThreadData.SetCurrRequest(ConvItem)
|
||||
|
||||
' ' vecchia versione
|
||||
' 'MyThreadData.SetCurrRequest(LastRequest.First())
|
||||
|
||||
' Dim Item As KeyValuePair(Of String, String) = MyThreadData.CurrRequest
|
||||
' Dim bOk As Boolean = Not IsNothing(Item)
|
||||
' If bOk Then
|
||||
|
||||
' ' avvio cronometro
|
||||
' 'stopWatch.Reset()
|
||||
' stopWatch.Restart()
|
||||
' ' svuoto vecchio set file della porta richiesta
|
||||
' Dim fileList As String() = Directory.GetFiles(sCurrDdfDir, Item.Key + ".*")
|
||||
' ' elimino vecchi
|
||||
' If Not IsNothing(fileList) Then
|
||||
' For Each sFile In fileList
|
||||
' Try
|
||||
' File.Delete(sFile)
|
||||
' Catch ex As Exception
|
||||
' End Try
|
||||
' Next
|
||||
' End If
|
||||
|
||||
' ' scrivo ddf
|
||||
' MyThreadData.SetThreadOperation(ThreadOperations.WritingDdf)
|
||||
' MyThreadData.SetDdfPath(sCurrDdfDir & "\" & Item.Key & ".ddf")
|
||||
' Dim sDdfPath As String = MyThreadData.sDdfPath
|
||||
' Try
|
||||
' File.WriteAllText(sDdfPath, Item.Value)
|
||||
' Catch ex As Exception
|
||||
' bOk = False
|
||||
' End Try
|
||||
|
||||
' If bOk Then
|
||||
' MyThreadData.SetThreadOperation(ThreadOperations.ProcessingDdf)
|
||||
|
||||
' Proc.StandardInput.WriteLine(ThreadIndex & "," & sDdfPath)
|
||||
|
||||
' MyThreadData.SetWaitProcAnswer(ThreadData.ProcComm.WaitingAnswer)
|
||||
' End If
|
||||
' End If
|
||||
' Else
|
||||
' Thread.Sleep(100)
|
||||
' End If
|
||||
'Else
|
||||
' Thread.Sleep(100)
|
||||
'End If
|
||||
Case ThreadData.ProcessStatuses.WAITINGANSWER
|
||||
Thread.Sleep(10)
|
||||
Case ThreadData.ProcessStatuses.ANSWERRECEIVED
|
||||
Dim NewProcessArgsResult As New ProcessArgsResult(MyThreadData.CurrRequest, MyThreadData.nProcResult)
|
||||
If Not IsNothing(m_delPostProcess) Then
|
||||
m_delPostProcess(NewProcessArgsResult)
|
||||
End If
|
||||
ArgumentsResultEnqueue(NewProcessArgsResult)
|
||||
'Dim Item As ProcessArgs = MyThreadData.CurrRequest
|
||||
'Dim sDdfPath As String = MyThreadData.sDdfPath
|
||||
'Dim bOk As Boolean = True
|
||||
'' salvo exe time...
|
||||
'stopWatch.Stop()
|
||||
'lExeTime = stopWatch.ElapsedMilliseconds
|
||||
'stopWatch.Restart()
|
||||
'Dim procResults As New List(Of CalcResultDTO)
|
||||
'Dim currRes As New CalcResultDTO
|
||||
'Dim fContent As String = ""
|
||||
'MyThreadData.SetThreadOperation(ThreadOperations.ReadingSvg)
|
||||
'' verifico esistenza file svg e lo carico
|
||||
'bOk = GetFileContent(Path.ChangeExtension(sDdfPath, "svg"), fContent)
|
||||
'' !!! ToDo: inserire TIPO di richiesta secondo quanto ricevuto....
|
||||
'' invio risposta
|
||||
'currRes.Validated = MyThreadData.nProcResult = 0 AndAlso bOk
|
||||
'currRes.DoorIdVers = Item.Key
|
||||
'' per ora cablato a svg, prendere da MimeType richiesta...
|
||||
'currRes.MimeType = "svg"
|
||||
|
||||
'' se NON fosse validato --> messo il messaggio...
|
||||
'If (currRes.Validated) Then
|
||||
' currRes.RawContent = fContent
|
||||
'Else
|
||||
' bOk = GetFileContent(Path.ChangeExtension(sDdfPath, "txt"), fContent)
|
||||
' currRes.ErrorMsg = fContent
|
||||
'End If
|
||||
'MyThreadData.SetThreadOperation(ThreadOperations.SendResult)
|
||||
|
||||
'procResults.Add(currRes)
|
||||
'Dim respPut As String = currWDC.SendProcResults(procResults)
|
||||
|
||||
'stopWatch.Stop()
|
||||
'lOtherTime = stopWatch.ElapsedMilliseconds
|
||||
'CurrPocStat.IncrementDoneRequest()
|
||||
'' aggiorno thread display...
|
||||
'UpdateThreadList(Item.Key, lExeTime, lOtherTime)
|
||||
'' cambio nomi file generati in old
|
||||
'Dim OldSvg As String = Path.ChangeExtension(sDdfPath, "svg")
|
||||
'Dim NewSvg As String = Path.GetDirectoryName(sDdfPath) & "\" & Path.GetFileNameWithoutExtension(sDdfPath) & "_old.svg"
|
||||
'Try
|
||||
' File.Delete(NewSvg)
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Delete(Path.ChangeExtension(NewSvg, "txt"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Delete(Path.ChangeExtension(NewSvg, "log"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Delete(Path.ChangeExtension(NewSvg, "nge"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Delete(Path.ChangeExtension(NewSvg, "ddf"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Move(OldSvg, NewSvg)
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Move(Path.ChangeExtension(OldSvg, "txt"), Path.ChangeExtension(NewSvg, "txt"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Move(Path.ChangeExtension(OldSvg, "log"), Path.ChangeExtension(NewSvg, "log"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Move(Path.ChangeExtension(OldSvg, "nge"), Path.ChangeExtension(NewSvg, "nge"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
'Try
|
||||
' File.Move(Path.ChangeExtension(OldSvg, "ddf"), Path.ChangeExtension(NewSvg, "ddf"))
|
||||
'Catch ex As Exception
|
||||
'End Try
|
||||
MyThreadData.SetProcessStatus(ThreadData.ProcessStatuses.NULL)
|
||||
End Select
|
||||
|
||||
End While
|
||||
' CurrPocStat.SetStopProc(DateTime.Now)
|
||||
If m_bStopProcess Then
|
||||
Proc.StandardInput.WriteLine("quit")
|
||||
End If
|
||||
End If
|
||||
|
||||
' CurrThreadStat.SetStopThread(DateTime.Now)
|
||||
MyThreadData.SetProcess(Nothing)
|
||||
' MyThreadData.SetThreadOperation(ThreadOperations.Closed)
|
||||
|
||||
End Sub
|
||||
|
||||
Private Sub Thread_OutputDataReceived(sender As Object, e As DataReceivedEventArgs)
|
||||
Dim sResult As String = e.Data
|
||||
If Not String.IsNullOrWhiteSpace(sResult) AndAlso sResult.StartsWith("#42315#,") Then
|
||||
Dim Results() As String = sResult.Split(","c)
|
||||
If Results.Count >= 2 Then
|
||||
Dim nIndex As Integer = -1
|
||||
Dim nResult As Integer = -1
|
||||
If Integer.TryParse(Results(1), nIndex) AndAlso nIndex >= 0 Then
|
||||
If Integer.TryParse(Results(2), nResult) AndAlso nResult >= 0 Then
|
||||
ThreadDataList(nIndex).SetProcResult(nResult)
|
||||
End If
|
||||
ThreadDataList(nIndex).SetProcessStatus(ThreadData.ProcessStatuses.ANSWERRECEIVED)
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
Public Class ThreadData
|
||||
|
||||
'Enum ThreadOperations As Integer
|
||||
' WaitingData = 1
|
||||
' FoundRequest = 2
|
||||
' WritingDdf = 3
|
||||
' ProcessingDdf = 4
|
||||
' ReadingSvg = 5
|
||||
' SendResult = 6
|
||||
' Closed = 10
|
||||
'End Enum
|
||||
|
||||
Public Enum ProcessStatuses As Integer
|
||||
NULL = 0
|
||||
WAITINGANSWER = 1
|
||||
ANSWERRECEIVED = 2
|
||||
TOBESTARTED = 10
|
||||
End Enum
|
||||
|
||||
Private m_ProcessStatus As ProcessStatuses = ProcessStatuses.TOBESTARTED
|
||||
Public ReadOnly Property ProcessStatus As ProcessStatuses
|
||||
Get
|
||||
Return m_ProcessStatus
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub SetProcessStatus(value As ProcessStatuses)
|
||||
m_ProcessStatus = value
|
||||
End Sub
|
||||
|
||||
Private m_CurrRequest As ProcessArgs
|
||||
Public ReadOnly Property CurrRequest As ProcessArgs
|
||||
Get
|
||||
Return m_CurrRequest
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub SetCurrRequest(value As ProcessArgs)
|
||||
m_CurrRequest = value
|
||||
End Sub
|
||||
|
||||
Private m_sDdfPath As String
|
||||
Public ReadOnly Property sDdfPath As String
|
||||
Get
|
||||
Return m_sDdfPath
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub SetDdfPath(value As String)
|
||||
m_sDdfPath = value
|
||||
End Sub
|
||||
|
||||
Private m_nProcResult As Integer
|
||||
Public ReadOnly Property nProcResult As Integer
|
||||
Get
|
||||
Return m_nProcResult
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub SetProcResult(value As Integer)
|
||||
m_nProcResult = value
|
||||
End Sub
|
||||
|
||||
'Private m_ThreadOperation As ThreadOperations
|
||||
'Public ReadOnly Property ThreadOperation As ThreadOperations
|
||||
' Get
|
||||
' Return m_ThreadOperation
|
||||
' End Get
|
||||
'End Property
|
||||
'Friend Sub SetThreadOperation(value As ThreadOperations)
|
||||
' m_ThreadOperation = value
|
||||
'End Sub
|
||||
|
||||
Private m_Process As Process
|
||||
Public ReadOnly Property Process As Process
|
||||
Get
|
||||
Return m_Process
|
||||
End Get
|
||||
End Property
|
||||
Friend Sub SetProcess(value As Process)
|
||||
m_Process = value
|
||||
End Sub
|
||||
|
||||
'Private m_ThreadStat As ThreadStat
|
||||
'Public ReadOnly Property ThreadStat As ThreadStat
|
||||
' Get
|
||||
' Return m_ThreadStat
|
||||
' End Get
|
||||
'End Property
|
||||
'Friend Sub SetThreadStat(value As ThreadStat)
|
||||
' m_ThreadStat = value
|
||||
'End Sub
|
||||
|
||||
End Class
|
||||
|
||||
Public Class ProcessArgs
|
||||
|
||||
Private m_nId As Integer
|
||||
Public ReadOnly Property nId As Integer
|
||||
Get
|
||||
Return m_nId
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Private m_sArgs As String
|
||||
Public ReadOnly Property sArgs As String
|
||||
Get
|
||||
Return m_sArgs
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Sub New(nId As Integer, sArgs As String)
|
||||
m_nId = nId
|
||||
m_sArgs = sArgs
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
Public Class ProcessArgsResult
|
||||
|
||||
Private m_ProcessArgs As ProcessArgs
|
||||
Public ReadOnly Property ProcessArgs As ProcessArgs
|
||||
Get
|
||||
Return m_ProcessArgs
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Private m_nResult As Integer
|
||||
Public ReadOnly Property nResult As Integer
|
||||
Get
|
||||
Return m_nResult
|
||||
End Get
|
||||
End Property
|
||||
Public Sub SetResult(nResult As Integer)
|
||||
m_nResult = nResult
|
||||
End Sub
|
||||
|
||||
Sub New(ProcessArgs As ProcessArgs, nResult As Integer)
|
||||
m_ProcessArgs = ProcessArgs
|
||||
m_nResult = nResult
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
@@ -84,7 +84,7 @@ Public Class JsonDoor
|
||||
End Property
|
||||
|
||||
<JsonConstructor>
|
||||
Sub New(nListIndex As Integer, nId As Integer, nCSVLine As Integer, sDDFName As String, sCSVName As String, nQuantity As Integer, dWidth As Double, dHeight As Double, dThickness As Double, CustomerParameters As List(Of CustomerParameter))
|
||||
Sub New(nListIndex As Integer, nId As Integer, nCSVLine As Integer, sDDFName As String, sCSVName As String, nQuantity As Integer, dWidth As Double, dHeight As Double, dThickness As Double, nState As DoorStates, CustomerParameters As List(Of CustomerParameter))
|
||||
m_nListIndex = nListIndex
|
||||
m_nId = nId
|
||||
m_nCSVLine = nCSVLine
|
||||
@@ -94,6 +94,7 @@ Public Class JsonDoor
|
||||
m_dHeight = dHeight
|
||||
m_dWidth = dWidth
|
||||
m_dThickness = dThickness
|
||||
m_nState = nState
|
||||
m_CustomerParameters = CustomerParameters
|
||||
End Sub
|
||||
|
||||
@@ -107,6 +108,7 @@ Public Class JsonDoor
|
||||
m_dHeight = Door.dHeight
|
||||
m_dWidth = Door.dWidth
|
||||
m_dThickness = Door.dThickness
|
||||
m_nState = Door.nState
|
||||
m_CustomerParameters = Door.CustomerParameters
|
||||
End Sub
|
||||
|
||||
|
||||
Reference in New Issue
Block a user