Avatar billede tblaster Nybegynder
21. august 2012 - 18:12 Der er 10 kommentarer og
1 løsning

Program til overvågning af mappe crasher efter noget tid

Hej

Jeg prøver at lave et program der hele tiden skal overvåge en mappe. Når den finder en ny fil i mappen skal den så udføre en konvertering af denne fil. Jeg har skrevet nedenstående kode som virker fint til at starte med. Men efter at den måske har kørt i en time så går programmet ned uden fejl. Er der en bedre måde at kode det på? Jeg vil desuden meget gerne have mulighed for at køre funktionen MakeFile() 2 gange parallelt på hver sin kerne (til overvågning af 2 forskellige mapper). Hvordan kan det gøres?

Jeg koder i Visual Basic Express 2010 og her er min kode:

Option Explicit On
Imports System
Imports System.IO
Imports System.Threading

Public Class Form1
    Public lineRead, Path1, AddText, PathConverter, WaitTime As String
    Public ConvertedCounter As Integer

    Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
        Me.Show()
        LoadSettings()
        MakeFile()
    End Sub

    Private Function MakeFile()
        Dim di As New DirectoryInfo(Path1)
        Dim fiArr As FileInfo() = di.GetFiles()

        Dim fil As FileInfo
        For Each fil In fiArr
            If fil.Extension = ".dnz" Then
                ' Check if .coz file exists
                Dim fInfo As New FileInfo(Path1 & "\" & Replace(fil.Name, ".dnz", ".coz"))
                Dim fInfo1 As New FileInfo(Path1 & "\" & Replace(fil.Name, ".dnz", ".coz." & AddText))
                If Not fInfo.Exists And Not fInfo1.Exists Then
                    ' Check if .dnz.tmp file exists
                    Dim fInfo2 As New FileInfo(Path1 & "\" & Replace(fil.Name, ".dnz", ".dnz.tmp"))
                    If fInfo2.Exists Then
                        ' Check if create time of file is > NOW - WaitTime
                        If DateDiff(DateInterval.Minute, fil.CreationTime, DateAdd(DateInterval.Minute, -WaitTime, Now)) > WaitTime Then
                            ' Check if last write time of file is > NOW - WaitTime
                            If DateDiff(DateInterval.Minute, fil.LastWriteTime, DateAdd(DateInterval.Minute, -WaitTime, Now)) > WaitTime Then
                                ' Only convert file if it is not older than 1 day
                                If DateDiff(DateInterval.Hour, fil.CreationTime, Now) < 24 Then

                                    Dim pInfo As New ProcessStartInfo()
                                    Dim p As Process = Process.Start(PathConverter, "Convert """ & Path1 & "\" & fil.Name & """ """ & Path1 & "\" & Replace(fil.Name, ".dnz", ".coz.") & AddText & "")

                                    Do While Not p.HasExited
                                        ' The last process is still running
                                        Threading.Thread.Sleep(1000)
                                        Application.DoEvents()
                                    Loop

                                    ' Rename file when the above process is done
                                    My.Computer.FileSystem.RenameFile(Path1 & "\" & Replace(fil.Name, ".dnz", ".coz.") & AddText, Replace(fil.Name, ".dnz", ".coz"))
                                    ConvertedCounter = ConvertedCounter + 1
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        Next fil

        For i = 1 To 10
            Threading.Thread.Sleep(1000)
            Application.DoEvents()
        Next
        MakeFile()
    End Function
End Class
Avatar billede tjp Mester
22. august 2012 - 11:49 #1
Opklarende spørgsmål - hvorfor kalder du MakeFile rekursivt? Ville måske være mindre hukommelseslugende at kalde den gentagent udefra i en løkke...
Fx (ikke testet):

    Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Activated
        Me.Show()
        LoadSettings()
        Do While True
            MakeFile()
            Application.DoEvents()
            Threading.Thread.Sleep(1000)
        Loop
    End Sub
Avatar billede tblaster Nybegynder
22. august 2012 - 12:01 #2
Godt spørgsmål, det havde jeg ikke lige tænkt på. Jeg har nu lavet den om som du foreslår så ser jeg om den stadig går ned. Men jeg tror ikke det er pga. hukommelse mangel for computeren jeg tester programmet på har 24 GB og jeg har aldrig set mit program bruge mere end ca. 100 mb.
Avatar billede tjp Mester
22. august 2012 - 15:04 #3
Det kommer an på hvor meget hukommelse programmet får tildelt - ikke hvor meget hukommelse der er på maskinen. Og da de rekursive kald aldrig returnerer, vil hukommelsesforbruget jo være støt stigende, da hvert kald lægger en klat data på stakken.
Avatar billede tblaster Nybegynder
22. august 2012 - 16:14 #4
Hvis jeg bruger din løsning med at lave en loop i min Form1_Activated, kender du så en måde hvorpå jeg kan have min MakeFile funktion kørende samtidigt på flere kerner, eks:


Kerne1:
        Do While True
            MakeFile(Parameter1)
            Application.DoEvents()
            Threading.Thread.Sleep(1000)
        Loop

Kerne2:
        Do While True
            MakeFile(Parameter2)
            Application.DoEvents()
            Threading.Thread.Sleep(1000)
        Loop
Avatar billede tjp Mester
22. august 2012 - 17:06 #5
Hmm, tror ikke jeg helt forstår dit begreb 'kerner'... :-)

Hvis du ønsker at overvåge 2 mapper og argumentet til MakeFile er stien til mappen, ku du vel bare kalde dem efterfølgende i samme loop:

Do While True
  MakeFile(Parameter1)
  MakeFile(Parameter2)
  Application.DoEvents()
  Threading.Thread.Sleep(1000)
Loop

Hvis de skal køre i hver sin tråd, ku du evt. starte programmet 2 gange med hver sin mappeparameter. Eller starte løkkerne i hver sin tråd i programmet...
Avatar billede tblaster Nybegynder
22. august 2012 - 17:14 #6
Ja, det er korrekt at jeg vil overvåge 2 mapper og derfor have dem til at køre på hver sin tråd. Jeg vil helst undgå at starte programmet 2 gange og er derfor interesseret i at have løkkerne kørende i hver sin tråd i programmet. Kan du hjælpe med hvordan det gøres?
Avatar billede tjp Mester
22. august 2012 - 17:34 #7
Er der nogen speciel grund til at de skal køre i hver sin tråd?
Avatar billede tblaster Nybegynder
22. august 2012 - 17:38 #8
Jeg vil gerne have at de køre samtidigt og dermed udnytter flere af computerens ressourcer. Den konvertering jeg laver kan tage omkring en time pr. fil og så vil det være træls at den først kigger mappe 2 igennem når den har været alle filer i mappen 1 igennem.
Avatar billede tjp Mester
23. august 2012 - 11:13 #9
OK, makes sense..

Jeg har ikke prøvet at lave flere tråde i VB, men mon ikke noget lignende det nedenstående kan gøre det? (Stadig ikke testet ;-) ):

Private parm As String

Private Sub InitiateThreads()
    Me.parm = "<sti til mappe1>"
    Dim t1 As New Thread(AddressOf DoWork)
    t1.Start()
    Me.parm = "<sti til mappe2>"
    Dim t2 As New Thread(AddressOf DoWork)
    t2.Start()
End Sub

Private Sub DoWork()
  Dim path As String = Me.parm
  Do While True
    MakeFile(path)
    Application.DoEvents()
    Threading.Thread.Sleep(1000)
  Loop
End Sub
Avatar billede tblaster Nybegynder
28. august 2012 - 21:31 #10
Tak for din hjælp ... det virker nu så smid et svar så skal du få nogle point.
Avatar billede tjp Mester
29. august 2012 - 10:51 #11
Jamen, velbekomme - here U R..
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester