Question Statistik with threads and Events

Novo

New member
Joined
Jan 15, 2009
Messages
2
Programming Experience
Beginner
Hello Community,

I have to Archive Files with Multithreads and now i have to implement a Statistic function.
Everytime a thread is finished with its work, it sends an Event with zipped Filesize, unzipped Filesize and Filepath to the main class.

There it should count the files, that all threads have done.

i did it this way:
Thread use a stat.ini file with SyncLock (so only one Thread can use it, all other Threads wait, till the first Thread is finished)
read the number, make number+1 and save the file.

The Problem:
it don't count correctly!

What can i do?
i could use SyncLock, Monitor or Invoke required

Mfg Novo



VB.NET:
'Everytime a Thread is finished, to this event
Public Sub NTStatistic(ByVal Dateiname As String, ByVal SizeUnzip As Integer, ByVal SizeZip As Integer)

        SyncLock ThreadLock
            Dim AnzahlFiles As Long
            Dim GezippteDatei As Long
            Dim UngezippteDatei As Long

            Try
                Dim TextAusDatei() As String = File.ReadAllText("stat.ini").Split(Environment.NewLine)

                AnzahlFiles = Val(TextAusDatei(0)) + 1
                GezippteDatei = Val(TextAusDatei(1)) + SizeZip
                UngezippteDatei = Val(TextAusDatei(2)) + SizeUnzip
            Catch
                '... das erste mal...
                AnzahlFiles = 1
                GezippteDatei = SizeZip
                UngezippteDatei = SizeUnzip
            End Try

            Dim Message As String = AnzahlFiles & Environment.NewLine _
                           & GezippteDatei.ToString & Environment.NewLine _
                           & UngezippteDatei.ToString & Environment.NewLine
            Try
                File.WriteAllText("stat.ini", Message)
            Catch ex As Exception
                Try
                    File.AppendAllText("stat.ini", Message)
                Catch er As Exception
                    Try
                        File.AppendAllText("stat.ini", Message)
                    Catch err As Exception
                        Try
                            File.AppendAllText("stat.ini", Message)
                        Catch errr As Exception
                            Try
                                File.AppendAllText("stat.ini", Message)
                            Catch errrr As Exception
                            End Try
                        End Try
                    End Try
                End Try
            End Try

        End SyncLock
    End Sub
 
Ugh!

Look into using a Mutex, to prevent more than one thread executing the NTStatistic at any one time. MAKE SURE that the code inside the mutex cannot become blocked forever..

I'd actually be tempted to make the threads add their statistics into a List(Of String), and then have the contents of the List written to file every X seconds (use a variable to track the time of the last write, and write if current time - that time is more than X seconds)

As a final point of note, youre allowed to put a try/catch in a loop, you don't have to nest them like that. You might want to consider putting some form of waiting in, or just report errors into e.g. the event viewer, update the time variable and the program will attempt to write again in X seconds time

VB.NET:
mutex.Wait()

Try

  myList.Add(STRING_TO_LOG)

  If (DateTime.Now - myLastWriteTime).TotalSeconds > 10 Then

    File.AppendAllLines(myList.ToArray(), "a.log") 'why ini? thats used for settings, not logs

    myList.Clear()

    myLastWriteTime = DateTime.Now

  End If

Catch ex as Exception

  EventLog.AddEntry(ex)

  myLastWriteTime = DateTime.Now 'upon error, try to write in 10 seconds rather than immediately

Finally

  mutex.Release()

End Try

This is pseudocode. It will not compile, buit is intended to describe what I diiscussed
Mutex Class (System.Threading)
 
note if youre not wanting to have a log file of many lines, then keep track of the totals using variables! The mutex will ensure that only one thread at a time updated the variables:

VB.NET:
mutex.WaitOne()

_totalZippedSize += zippedSize
_totalUnzippedSize += unzippedSize
_totalFiles += fileCount

'do whatver with these statistics.. but DONT read and write them to a file..
' write only. read them at startup if you have to, but reading during running 
'is a silly idea!
'Also note that if you forever read and write the file,eventually the numbers
' inside will get too big to hold ina n integer or a Long, so think about your
' logging strategy

mutex.ReleaseMutex()
 
Hey
thanks for your fast answer.
so i have to look, what is mutex, thanks for your idea.

The best thing is to use a global variable to count the size and number of files and write the variable into a file everx secounds ...

But how to do that?
i can not use a public shared variable.
The different Threads cannot access it!
 
Last edited:
Addressing the SyncLock problem would be better, SyncLock/Monitor is preferred over a local Mutex. You haven't explained the use of your "ThreadLock" sync object at all, also if you're running these threads from different class instances the sync object need to be Shared.

I'm not sure what you mean by "event" here, the NTStatistic method does not have an event signature. How is all this set up? Is NTStatistic asynchronous, or is it invoked on main thread?
i can not use a public shared variable.
The different Threads cannot access it!
Why not? And why do you think it has to be Shared?

If you just want to update an Integer/Long variable you also don't need to lock a code block, Interlocked.Increment can update the variable value safe between threads.
 
The use of a locked region in my pseudocode was to ensure that only one thread would attempt to write the file, and only after a specified period of time had elapsed.

But how to do that?
Did you bother to read my post?
 

Latest posts

Back
Top