Problems with threads. Threads disappearing?
Hello,
I have made an application to send and receive big amounts of XML files from and to a lot of other PC's. All these PC's (workstations) act like an FTP server. So basically I have to put and get all the recent XML files to and from these workstations (these workstations are equipped with Windows XP CE). We have in total about 20 workstations now, but this will evolve to about 150 workstations.
We use the FTP .NET component from DART.
Basically I made a class (called FTPCollection), each class has an Arraylist containing IP addresses to some of the workposts. Every FTPCollection has his own BeginPut and EndPut public method. With BeginPut and Endput we launch a separate thread in which an infinite loop (while not EndRequested) sends or receives the files (and deleting them on server or client side) from every workstation.
So when this collection has e.g. three workstations we first get the files from the first, then from the second, then from the third. Again from the first, then the second, then from the third. And so on... Same thing for sending (put).
After the last workstation has been updated I put the thread to sleep for 10 seconds (to save a bit on network traffic) and write some stuff to a log file.
We have no more than 5 collections running (so basically 10 FTP instances).
Now our problem: it seems that after a time (more than a day) our threads disappear. I don't have exceptions, I'm not notified of the infinite loop being ended (would be logged, but I see nothing).
I'm not a big expert on threading yet (I'm reading about it for the moment, but this thing is bugging us for weeks. Does anyone has an idea?
Thanks,
Dries
Hereunder is the code for the class:
Imports System.Threading
Imports Dart.PowerTCP.Ftp.Ftp
Public Class FTPCollection
#Region "Shared members"
Private Shared NumberOfProcesses As Integer = 0
#End Region
#Region "Inhereted properties and methods"
Public Collection As System.Collections.ArrayList
#End Region
#Region "Constructors"
Public Sub New(ByVal Index As Integer)
Collection = New System.Collections.ArrayList()
CollectionIndex = Index
PutStopped = True
GetStopped = True
End Sub
#End Region
#Region "Private EventHandlers"
Public Event EndPutCollection(ByVal CollectionIndex As Integer)
Public Event EndGetCollection(ByVal CollectionIndex As Integer)
#End Region
#Region "Private variables"
Private CollectionIndex As Integer
Private Put_Thread As Thread
Private Get_Thread As Thread
Private FTPGet As Dart.PowerTCP.Ftp.Ftp = New Dart.PowerTCP.Ftp.Ftp()
Private FTPPut As Dart.PowerTCP.Ftp.Ftp = New Dart.PowerTCP.Ftp.Ftp()
Private StopGetFlag As Boolean
Private StopPutFlag As Boolean
Private PutStopped As Boolean
Private GetStopped As Boolean
#End Region
#Region "Public methods"
Public Sub StartPut()
StopPutFlag = False
PutStopped = False
Dim Put_Thread As New Thread(AddressOf Me.PutEntries)
Put_Thread.Start()
End Sub
Public Sub StartGet()
StopGetFlag = False
GetStopped = False
Dim Get_Thread As New Thread(AddressOf Me.GetEntries)
Get_Thread.Start()
End Sub
Public Sub StopPut()
StopPutFlag = True
End Sub
Public Sub StopGet()
StopGetFlag = True
End Sub
Public Function PutFTPStopped() As Boolean
Return PutStopped
End Function
Public Function GetFTPStopped() As Boolean
Return GetStopped
End Function
#End Region
#Region "Private methods"
Private Sub PutEntries()
Dim myEnumerator As System.Collections.IEnumerator = Collection.GetEnumerator()
Dim PutCarFiles() As Dart.PowerTCP.Ftp.FtpFile
Dim PutCarFile As Dart.PowerTCP.Ftp.FtpFile
Dim EntryID As String
While Not StopPutFlag 'Only stop this loop when we're changing this flag value
While myEnumerator.MoveNext() And Not StopPutFlag
If CType(myEnumerator.Current, HMI_Entry).Online Then 'Only put files via FTP if the remote host is online
Try
EntryID = CType(myEnumerator.Current, HMI_Entry).HMI_ID.ToString
FTPPut = New Dart.PowerTCP.Ftp.Ftp()
FTPPut.Server = CType(myEnumerator.Current, HMI_Entry).IP
FTPPut.Username = System.Configuration.ConfigurationSettings.AppSett ings("FTPUser")
FTPPut.Password = System.Configuration.ConfigurationSettings.AppSett ings("FTPPassword")
FTPPut.Timeout = CInt(System.Configuration.ConfigurationSettings.Ap pSettings("FTPEOLTimeOut"))
FTPPut.ServerPort = 21
FTPPut.FileType = Dart.PowerTCP.Ftp.FileType.Image
PutCarFiles = FTPPut.Put(System.Configuration.ConfigurationSetti ngs.AppSettings("Car2HMIPath") & "\" & EntryID & "\", "*.xml", "IP/IN/", False)
If Not (PutCarFiles Is Nothing) Then
For Each PutCarFile In PutCarFiles
frmMain.AddFTPText(EntryID & " - " & PutCarFile.LocalFileName.Substring(PutCarFile.Loca lFileName.LastIndexOf("\") + 1) & " was " & PutCarFile.Status.ToString, frmMainForm.FTPTextDirection.Car2HMI, EntryID)
If (PutCarFile.Status = Dart.PowerTCP.Ftp.FtpFileStatus.TransferCompleted And PutCarFile.Exception Is Nothing) Then
'If needed we will backup this file
If CType(System.Configuration.ConfigurationSettings.A ppSettings("BackupCar2HMIFiles"), Boolean) Then
If WaitForExclusiveAccessToFile(PutCarFile.LocalFileN ame) Then
Try
BackupFile(PutCarFile.LocalFileName, System.Configuration.ConfigurationSettings.AppSett ings("Car2HMIBackupPath").ToString & "\" & EntryID, "bak")
Catch BackupEx As Exception
System.IO.File.Delete(PutCarFile.LocalFileName)
Exit Sub
End Try
End If
Else
System.IO.File.Delete(PutCarFile.LocalFileName)
End If
End If
Next
PutCarFile = Nothing
End If
PutCarFiles = Nothing
FTPPut.Close()
FTPPut = Nothing
Catch ex As System.Net.Sockets.SocketException
'FTPHost was unreachable
CType(myEnumerator.Current, HMI_Entry).Online = False
FTPPut = Nothing
Catch ex As Exception
FTPPut = Nothing
'Unspecified error
End Try
Else
WriteFTPPutLog(EntryID & " seems off line", CollectionIndex)
End If
End While
myEnumerator.Reset()
While myEnumerator.MoveNext And Not StopPutFlag
If Not CType(myEnumerator.Current, HMI_Entry).Online Then
Try
If Echo(CType(myEnumerator.Current, HMI_Entry).IP) Then
CType(myEnumerator.Current, HMI_Entry).Online = True
'WriteFTPPutLog("Ping to: " & CType(myEnumerator.Current, HMI_Entry).IP.ToString & " was a success!", CollectionIndex)
Else
'WriteFTPPutLog("Ping to: " & CType(myEnumerator.Current, HMI_Entry).IP.ToString & " failed!", CollectionIndex)
End If
Catch ex As Exception
'WriteFTPErrorLog(CollectionIndex, " Algemene exception tijdens het pingen van: " & EntryID & ": " & ex.ToString & ex.Message.ToString, False)
End Try
End If
End While
myEnumerator.Reset()
WriteFTPErrorLog(CollectionIndex, "gaat in de sleep", False)
System.Threading.Thread.CurrentThread.Sleep(CInt(S ystem.Configuration.ConfigurationSettings.AppSetti ngs("FTPSendTimerInterval")))
WriteFTPErrorLog(CollectionIndex, "uit de sleep", False)
End While
PutStopped = True 'If we get here, it means we stopped PUT files
End Sub
Private Sub GetEntries()
Dim myEnumerator As System.Collections.IEnumerator = Collection.GetEnumerator()
Dim GetCarFiles() As Dart.PowerTCP.Ftp.FtpFile
Dim GetCarFile As Dart.PowerTCP.Ftp.FtpFile
Dim EntryID As String
While Not StopGetFlag 'Only stop this loop when we're changing this flag value
While myEnumerator.MoveNext() And Not StopGetFlag
If CType(myEnumerator.Current, HMI_Entry).Online Then 'Only put files via FTP if the remote host is online
Try
EntryID = CType(myEnumerator.Current, HMI_Entry).HMI_ID.ToString
FTPGet = New Dart.PowerTCP.Ftp.Ftp()
While FTPGet.Busy
Dim SleepCounter As Integer
System.Threading.Thread.Sleep(100)
SleepCounter += 1
If SleepCounter >= 10 Then
'WriteFTPErrorLog(CollectionIndex, "FTPGet closes not fast enough", True)
Exit While
End If
End While
FTPGet.Server = CType(myEnumerator.Current, HMI_Entry).IP
FTPGet.Username = System.Configuration.ConfigurationSettings.AppSett ings("FTPUser")
FTPGet.Password = System.Configuration.ConfigurationSettings.AppSett ings("FTPPassword")
FTPGet.Timeout = CInt(System.Configuration.ConfigurationSettings.Ap pSettings("FTPEOLTimeOut"))
FTPGet.ServerPort = 21
FTPGet.FileType = Dart.PowerTCP.Ftp.FileType.Image
GetCarFiles = FTPGet.Get("IP/OUT/", "*.xml", System.Configuration.ConfigurationSettings.AppSett ings("HMI2CarPath") & "\" & EntryID, False)
If Not (GetCarFiles Is Nothing) Then
For Each GetCarFile In GetCarFiles
frmMain.AddFTPText(EntryID & " - " & GetCarFile.LocalFileName.Substring(GetCarFile.Loca lFileName.LastIndexOf("\") + 1) & " was " & GetCarFile.Status.ToString, frmMainForm.FTPTextDirection.HMI2Car, EntryID)
If (GetCarFile.Status = Dart.PowerTCP.Ftp.FtpFileStatus.TransferCompleted And GetCarFile.Exception Is Nothing) Then
Try
FTPGet.Delete(GetCarFile.RemoteFileName, True, False)
Catch ex As Exception
'WriteFTPErrorLog(CollectionIndex, "Error during Deleting file from " & EntryID & " " & GetCarFile.LocalFileName, True)
End Try
End If
Next
GetCarFile = Nothing
End If
GetCarFiles = Nothing
FTPGet.Close()
FTPGet = Nothing
Catch ex As System.Net.Sockets.SocketException
FTPGet.Close()
FTPGet = Nothing
WriteFTPErrorLog(CollectionIndex, "SocketException tijdens het getten van: " & EntryID & ": " & ex.ToString & ex.Message.ToString, True)
'FTPHost was unreachable
'CType(myEnumerator.Current, HMI_Entry).Online = False
Catch ex As Exception
WriteFTPErrorLog(CollectionIndex, " Algemene exception tijdens het getten van: " & EntryID & ": " & ex.ToString & ex.Message.ToString & "FtpGet.Busy =" & FTPGet.Busy.ToString, True)
FTPGet.Close()
FTPGet = Nothing
'Unspecified error
'WAT HIER DOEN?
End Try
Else
'WriteFTPGetLog(EntryID & " seems off line", CollectionIndex)
End If
End While
myEnumerator.Reset()
'MessageBox.Show("Maak hier mechanisme die de foutieve HMI's gaat pingen")
WriteFTPErrorLog(CollectionIndex, "gaat in Sleep", True)
System.Threading.Thread.CurrentThread.Sleep(CInt(S ystem.Configuration.ConfigurationSettings.AppSetti ngs("FTPReceiveTimerInterval")))
WriteFTPErrorLog(CollectionIndex, "uit de sleep", True)
End While
GetStopped = True 'If we get here, it means we stopped GET files
WriteFTPErrorLog(CollectionIndex, "GetStopped = true. We stoppen de FTPGet van deze collectie. Laatste HMI was : " & EntryID & ":" & GetCarFile.LocalFileName, True)
End Sub
#End Region
End Class
|