14. februar 2007 - 11:11Der er
26 kommentarer og 1 løsning
filen bliver kopieret mere end en gang når ændret?
Hej eksperter,
Jeg har et lille problem med et program jeg er ved at lave. Programmet skal kopier en fil fra netværket til maskinen når filen på netværket ændre sig. Til det bruger jeg filesystemwatcher, og mit problem er at hver gang jeg retter i den bgi fil (fil til programmet bginfo) så kopier den filen 5 gange istedet for kun en?
Det er koden: Imports System Imports System.IO Imports System.Diagnostics Public Class main
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length > 1 Then Application.Exit() End If Try '' Copy the file from the network path File.Copy(PathToFileToWatch & FileToWatch, PathToCopyTo & FileToWatch, True) Shell(PathToCopyTo & "Bginfo.exe /timer:0 /I""" & PathToCopyTo & FileToWatch & """", AppWinStyle.Hide, True) MsgBox("Runned from the startup of the program") Run() Catch ex As System.Exception '' Error handler errortext = _ "Error number: " & Err.Number & vbNewLine & _ "Error source: " & ex.StackTrace & vbNewLine & _ "Error descripton: " & ex.Message & vbNewLine EventLog.WriteEntry("BgInfoAgent", errortext, EventLogEntryType.Error) End Try End Sub
<Security.Permissions.PermissionSet(Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _ Private Shared Sub Run()
'' It creates the FileSystemWatcher Dim watcher As New FileSystemWatcher() watcher.Path = PathToFileToWatch ' Here it watches for changes in LastAccess and LastWrite time. watcher.NotifyFilter = (NotifyFilters.LastWrite Or NotifyFilters.Size)
'' Begin watching. watcher.EnableRaisingEvents = True
End Sub
Private Shared Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs) '' Wait 5 sec. before copying System.Threading.Thread.Sleep(5000) ''Copy the file File.Copy(PathToFileToWatch & FileToWatch, PathToCopyTo & FileToWatch, True) ''Run the command to update the background on the desktop Shell(PathToCopyTo & "Bginfo.exe /timer:0 /I""" & PathToCopyTo & FileToWatch & """", AppWinStyle.Hide, True) MsgBox("Runned from onChanged") End Sub End Class
Filesystem watcher kan godt komme med flere events. i onchange kan du lave noget alá
dim onChangeRunning as boolean = false Private Shared Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs) '' Wait 5 sec. before copying if not(onChangeRunning) then onChangeRunning = true System.Threading.Thread.Sleep(5000) ''Copy the file File.Copy(PathToFileToWatch & FileToWatch, PathToCopyTo & FileToWatch, True) ''Run the command to update the background on the desktop Shell(PathToCopyTo & "Bginfo.exe /timer:0 /I""" & PathToCopyTo & FileToWatch & """", AppWinStyle.Hide, True) MsgBox("Runned from onChanged") onChangeRunning = false end if End Sub
Hvor galt er jeg med den: (Den kopier nu slet ikke når bgi filen er ændret :( ) Dim TimeFired As DateTime
Private Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs) '' Wait 5 sec. before copying If (e.FullPath = PathToFileToWatch & FileToWatch And TimeFired.Subtract(DateTime.Now).TotalMilliseconds < 50) Then Return End If
System.Threading.Thread.Sleep(5000) ''Copy the file File.Copy(PathToFileToWatch & FileToWatch, PathToCopyTo & FileToWatch, True) ''Run the command to update the background on the desktop Shell(PathToCopyTo & "Bginfo.exe /timer:0 /I""" & PathToCopyTo & FileToWatch & """", AppWinStyle.Hide, True) MsgBox("Runned from onChanged") End Sub
Du er ikke gal på den men jeg var lidt hurtig med linket. Efter at have testet lidt mere er jeg kommet frem til følgende som i min test opstilling fungere:
Dim TimeFired As DateTime = DateTime.Now Private Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs) '' Wait 5 sec. before copying If (DateTime.Now.Subtract(TimeFired).TotalMilliseconds < 50) Then Exit Sub End If
System.Threading.Thread.Sleep(5000) ''Copy the file File.Copy(PathToFileToWatch & FileToWatch, PathToCopyTo & FileToWatch, True) ''Run the command to update the background on the desktop Shell(PathToCopyTo & "Bginfo.exe /timer:0 /I""" & PathToCopyTo & FileToWatch & """", AppWinStyle.Hide, True) MsgBox("Runned from onChanged") End Sub
Ups der er ryget en linie ud under copy paste : If (DateTime.Now.Subtract(TimeFired).TotalMilliseconds < 50) Then Exit Sub End If TimeFired = DateTime.Now
Det vil være interesant at vide på hvilke tidspunkter onchange kaldes. f.eks. med en debug.writeline(datetime.now.tostring("HH:mm:ss:fff")) i starten af onchange.
Nope: 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Drawing\2.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities.Sync\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.Sync.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\Documents and Settings\Seid.Krvavac\My Documents\Visual Studio 2005\Projects\BgInfoAgent\BgInfoAgent\bin\Release\BgInfoAgent.vshost.exe', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Deployment\2.0.0.0__b03f5f7f11d50a3a\System.Deployment.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Xml\2.0.0.0__b77a5c561934e089\System.Xml.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualBasic\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll', No symbols loaded. The thread 0x1668 has exited with code 0 (0x0). The thread 0x1050 has exited with code 0 (0x0). 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.Forms.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System\2.0.0.0__b77a5c561934e089\System.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Drawing\2.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities.Sync\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.Sync.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\Documents and Settings\Seid.Krvavac\My Documents\Visual Studio 2005\Projects\BgInfoAgent\BgInfoAgent\bin\Release\BgInfoAgent.vshost.exe', No symbols loaded. The program '[4296] BgInfoAgent.vshost.exe: Managed' has exited with code 0 (0x0). 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Deployment\2.0.0.0__b03f5f7f11d50a3a\System.Deployment.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Xml\2.0.0.0__b77a5c561934e089\System.Xml.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\Microsoft.VisualBasic\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll', No symbols loaded. A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in Microsoft.VisualStudio.HostingProcess.Utilities.dll The thread 0x1328 has exited with code 0 (0x0). The thread 0x12fc has exited with code 0 (0x0). 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\Documents and Settings\Seid.Krvavac\My Documents\Visual Studio 2005\Projects\BgInfoAgent\BgInfoAgent\bin\Release\BgInfoAgent.exe', Symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Runtime.Remoting\2.0.0.0__b77a5c561934e089\System.Runtime.Remoting.dll', No symbols loaded. 'BgInfoAgent.vshost.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_MSIL\System.Configuration\2.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', No symbols loaded.
Er debug.writeline linie 1 i sub onchange? udfra ovenstående tidspunkter er der jo mere end 5 sekunder mellem hvergang onchange bliver kaldt. Updateres filen ca. hver 10 sekund? hvis ikke så prøv at udkommentere alt efter thread.sleep i onchange og indsæt en debug.writeline(datetime.now.tostring("HH:mm:ss:fff") + " file import") hvad bliver resultatet så?
Nej filen opdateres kun en gang, og tror ikke at programmet bginfo gør noget da det køre fint i Sub Form1_Load Og ja debug.writeline var den første linie i onchanged sub. Det er output: 09:21:12:869 09:21:18:137 file import 09:21:18:167 09:21:23:174 file import 09:21:23:174 09:21:28:181 file import 09:21:28:181 09:21:33:179 file import 09:21:33:189 09:21:38:186 file import
og sådan ser sub'en ud pt: Dim TimeFired As DateTime = DateTime.Now Private Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs) Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff")) If (DateTime.Now.Subtract(TimeFired).TotalMilliseconds < 50) Then Exit Sub End If TimeFired = DateTime.Now
'' Wait 5 sec. before copying System.Threading.Thread.Sleep(5000) Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + " file import") ''Copy the file 'File.Copy(PathToFileToWatch & FileToWatch, PathToCopyTo & FileToWatch, True) ''Run the command to update the background on the desktop 'Shell(PathToCopyTo & "Bginfo.exe /timer:0 /I""" & PathToCopyTo & FileToWatch & """", AppWinStyle.Hide, True) 'MsgBox("Runned from onChanged") End Sub
efter lidt mere research har jeg et projekt som fungere perfekt. hvis der kommer f.eks. 5 events bliver onchange kaldt 5 gange efter hinanden og da hver tager minimum 5 sekunder vil vi se resultatet som ovenstående. Prøv at kigge på følgende projekt Visual Studio console projekt: Option Strict On Option Explicit On
Imports System.io Module Module1 Private t As System.Threading.Thread = New System.Threading.Thread(AddressOf DoWork) Private f As FileSystemwatcher Sub Main() Dim s As String f = New FileSystemWatcher f.IncludeSubdirectories = False f.NotifyFilter = NotifyFilters.LastAccess Or NotifyFilters.LastWrite f.Path = "c:\temp\" f.Filter = "test.txt" AddHandler f.Changed, AddressOf OnChanged f.EnableRaisingEvents = True Console.WriteLine("press enter to terminate") s = Console.ReadLine f.EnableRaisingEvents = False f.Dispose() End Sub
Private timeFired As DateTime = DateTime.Now Private Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs) Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "onchange start") If (DateTime.Now.Subtract(timeFired).TotalMilliseconds < 50) Then Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "onchange filtered") Exit Sub End If timeFired = DateTime.Now If t.ThreadState <> Threading.ThreadState.Running Then t = New System.Threading.Thread(AddressOf DoWork) t.Start() End If End Sub
Private Sub DoWork() System.Threading.Thread.Sleep(5000) Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "DoWork") End Sub End Module
Den gør det samme i dit program, det er outputtet: 10:38:54:242onchange start 10:38:54:322onchange start 10:38:54:322onchange filtered 10:38:54:332onchange start 10:38:54:332onchange filtered 10:38:56:275onchange start 10:38:59:309DoWork The thread '<No Name>' (0xe84) has exited with code 0 (0x0). 10:39:01:282DoWork The thread '<No Name>' (0x11c0) has exited with code 0 (0x0).
Det er koden så du kan se hvad jeg har rettet i: Option Strict On Option Explicit On
Imports System.io Module Module1 Private t As System.Threading.Thread = New System.Threading.Thread(AddressOf DoWork) Private f As FileSystemwatcher Sub Main() Dim s As String f = New FileSystemWatcher f.IncludeSubdirectories = False f.NotifyFilter = NotifyFilters.LastAccess Or NotifyFilters.LastWrite f.Path = "\\pepsict\newdfs\DK-Desktop_Info\BgInfo_Equipment\" f.Filter = "Eq_Info.bgi" AddHandler f.Changed, AddressOf OnChanged f.EnableRaisingEvents = True Console.WriteLine("press enter to terminate") s = Console.ReadLine f.EnableRaisingEvents = False f.Dispose() End Sub
Private timeFired As DateTime = DateTime.Now Private Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs) Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "onchange start") Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "onchange start") If (DateTime.Now.Subtract(timeFired).TotalMilliseconds < 50) Then Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "onchange filtered") Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "onchange filtered") Exit Sub End If timeFired = DateTime.Now If t.ThreadState <> Threading.ThreadState.Running Then t = New System.Threading.Thread(AddressOf DoWork) t.Start() End If End Sub
Private Sub DoWork() System.Threading.Thread.Sleep(5000) Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "DoWork") Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff") + "DoWork") End Sub End Module
Det er outputtet hvis jeg bruger en txt fil som jeg retter i: 10:49:29:456onchange start 10:49:30:137onchange start 10:49:30:137onchange filtered 10:49:30:137onchange start 10:49:30:147onchange filtered 10:49:30:157onchange start 10:49:35:134DoWork The thread '<No Name>' (0x1178) has exited with code 0 (0x0). 10:49:35:164DoWork
Det hjælper da på den dowork bliver godt nok kaldt 2 gange. kan man forestille sig at det tager ca. 2 sek at skrive bgi filen?
tror det funger hvis du retter If (DateTime.Now.Subtract(timeFired).TotalMilliseconds < 50) Then til If (DateTime.Now.Subtract(timeFired).TotalMilliseconds < 10000) Then
så skal der gå 10 sekunder mellem hver gang dowork kaldes
Det var da rart at man kunne få skovlen under den!
Synes godt om
Ny brugerNybegynder
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.