473,405 Members | 2,279 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

File Copier and Verifier Threads

Hi,

I'm working on an application that copies the files the moment these are created in the directory and paste's to some remote place.
The thing that is making some problem; i want this process in two threads, one to copy the file and the other to verify that its copied perfectly. these threads should run simultaneously so that the moment the file copied it should be verfied as well.

I have done with the both component but how to implement them in threads, im stuck. is there any best example i can use?
Really need some professional support.
Thanks!
Mar 31 '08 #1
17 2249
vanc
211 Expert 100+
Hi,

I'm working on an application that copies the files the moment these are created in the directory and paste's to some remote place.
The thing that is making some problem; i want this process in two threads, one to copy the file and the other to verify that its copied perfectly. these threads should run simultaneously so that the moment the file copied it should be verfied as well.

I have done with the both component but how to implement them in threads, im stuck. is there any best example i can use?
Really need some professional support.
Thanks!
There are many ways to deal with your issue. If you research a bit about threading, I believe you can easily synchronize between threads. You can make a thread wait till the other thread conduct its work or you can lock the next resource until the other thread verify the old resource, blah blah blah.
Looking for Thread Synchronization, it will help. Cheers.
Mar 31 '08 #2
balabaster
797 Expert 512MB
Your question may seem simple at first glance, but really, you've asked many questions:

Q: What should you use to copy the files?
A: System.IO.File.Copy(SourceFile, DestinationFile)

Q: What should you use to monitor and see if files are added or changed?
A: System.IO.FileSystemWatcher

Q: How do you make sure the file copied properly?
A: Use System.Security.Cryptography to generate an MD5 signature for the original file, do the same for the copy. If the MD5 is the same, two files are identical - the copy was successful.

Q: How do you achieve asynchronously?
A: Use System.Threading to process asynchronously. Things to watch out for - the filesystemwatcher flags multiple events for a single file change/creation - so you have to code a queuing system to prevent needless superfluous copies. It seems to me that the copy and the verification process need not be in two separate threads. You can't verify the copy is perfect until it's been copied - so you may as well do that all in a single process.

Q: How do you spin off a new thread?
A:
Expand|Select|Wrap|Line Numbers
  1. Dim FileName As String = "FileToCopy.txt"
  2. Dim oThrd As New System.Threading.Thread(AddressOf MyWorkerMethod)
  3. oThrd.Start(FileName)
  4.  
  5. Private Sub MyWorkerMethod(ByVal Args As Object)
  6.  
  7.   'Copy file and verify copy
  8.  
  9. End Sub
I hope all that points you in the right direction...
Mar 31 '08 #3
Thanks,
The guidelines are useful and using this approach i can explain some further points as well.

1 - This copy process should be done by the Window Service and the copy will be executed on the network.

2 - I need some messages among the threads; i.e. i have three threads;

a) - SourceQueue Thread:- This thread makes a queue for all the files when these were created.

b) - Copier Thread:- This thread reads the SourceQueue Thread and whenever a new file is available, this thread copies it to the destination. Then informs the Verifier thread to verify the copied file and gets back to the SourceQueue to get another file.

c) - Verifier Thread:- This thread waits for the Copier Thread and when gets the message then verifies the copied file and update the SourceQueue Thread (Or some DB Location) that the file has been verified successfully.

This is the architecture im looking for; the major issue in this approach is the messaging among the threads. Also the copier sends the confirmation when it completely copies the file.
One more issue that what if the file is in use by the other user when copier tries to copy it? And when it gets the file; the file must be locked so that cant be used by any other user during the copy/move. (Exclusive Access)

I think now you can have a better view on this approach.

Please advice!
Mar 31 '08 #4
Adding one more approach; that can we have a shared location where these three threads post their status and get their next task. I dont think that should be the Thread Pool as i only like to have three threads that perform all the stuff.

If we use this approach then what should be this shared location; i.e. what is the most feasible option for this;
- An In-Memory List/ Array
- Database table
- MSMQ

What should be the best way and how i can get this done; kindly suggest?
Mar 31 '08 #5
Hi All!

Any master suggestions, reply, comments, best practices?
Apr 1 '08 #6
balabaster
797 Expert 512MB
It seems that the only issue you're now facing is how to pass messages and how to trigger a thread to start...rather than messaging between threads, correct?

The code I posted above shows you how to do this.

I would use some variation of the following mechanism (I've also attached the VB Module that I wrote - just remove the .txt extension to use it). It's a quick hack that needs a couple of bits...but it does the core of what you're after. I'd imagine you'd want a MaximumRetries property so that it doesn't keep retrying failed files infinitely which it will do currently. But that should get you going in the right direction.

Expand|Select|Wrap|Line Numbers
  1. Imports System.Security.Cryptography
  2. Imports System.Threading
  3. Imports System.Text
  4. Imports System.IO
  5.  
  6. Module Module1
  7.  
  8.     Class BinaryCopyObject
  9.  
  10.         Private _File1 As String
  11.         Private _File2 As String
  12.  
  13.         Public Property File1() As String
  14.             Get
  15.                 Return _File1
  16.             End Get
  17.             Set(ByVal value As String)
  18.                 _File1 = value
  19.             End Set
  20.         End Property
  21.  
  22.         Public Property File2() As String
  23.             Get
  24.                 Return _File2
  25.             End Get
  26.             Set(ByVal value As String)
  27.                 _File2 = value
  28.             End Set
  29.         End Property
  30.  
  31.         Public Shared Function Compare(ByVal File1 As String, ByVal File2 As String) As Boolean
  32.             Dim md5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
  33.             md5.ComputeHash(File.ReadAllBytes(File1))
  34.             Dim hash1 As Byte() = md5.Hash
  35.             md5.ComputeHash(System.IO.File.ReadAllBytes(File2))
  36.             Dim hash2 As Byte() = md5.Hash
  37.             Return (Convert.ToBase64String(hash1) = Convert.ToBase64String(hash2))
  38.         End Function
  39.  
  40.         Public Function IsMatch() As Boolean
  41.             Return Compare(_File1, _File2)
  42.         End Function
  43.     End Class
  44.  
  45.     Private InputDirectory As String = "C:\AppTesting\Input"
  46.     Private OutputDirectory As String = "C:\AppTesting\Output"
  47.     Private ContinueProcess As New Threading.ManualResetEvent(False)
  48.     Private ProcessQueue As New Queue(Of String)
  49.     Private StopProcessingFlag As Boolean = False 'Allows us to stop the process thread cleanly
  50.     Private WithEvents oWatcher As FileSystemWatcher
  51.  
  52.     'Check the file to make sure we have exclusive access.  No point in processing a file we
  53.     'haven't finished copying yet.
  54.     Private Function FileLock(ByVal Filepath As String, ByVal TimeOut As Integer) As Boolean
  55.         Dim StartTime As Date = Now()
  56.         While True
  57.             If (TimeOut > 0) AndAlso (DateDiff(DateInterval.Second, StartTime, Now) > TimeOut) Then Exit While
  58.             Try
  59.                 Dim oStrm As System.IO.FileStream = System.IO.File.OpenWrite(Filepath)
  60.                 oStrm.Close()
  61.                 oStrm.Dispose()
  62.                 Return True
  63.             Catch ex As Exception
  64.             End Try
  65.             'Release thread to other threads until the next thread cycle
  66.             Threading.Thread.Sleep(0)
  67.         End While
  68.         Return False
  69.     End Function
  70.  
  71.     'Spit out a messages to the console
  72.     Private Sub WriteEntryToLog(ByVal Entry As String)
  73.         Console.WriteLine(Entry)
  74.     End Sub
  75.  
  76.     'This is the method that verifies the file copy was successful.  If it wasn't, it deletes
  77.     'the copy and requeues it.  You should add a mechanism in here so that the file isn't requeued
  78.     'if it fails more than a certain amount of times.
  79.     Private Sub VerifyThread(ByVal Args As Object)
  80.         Dim oVO As BinaryCopyObject = DirectCast(Args, BinaryCopyObject)
  81.         If Not oVO.IsMatch() Then
  82.             WriteEntryToLog(String.Format("{0} copy wasn't successful. Deleting and retrying.", oVO.File1))
  83.             System.IO.File.Delete(oVO.File2) 'Delete the copy
  84.             AddFileToProcessQueue(oVO.File1) 'Requeue the original
  85.         Else
  86.             WriteEntryToLog(String.Format("{0} copied and verified successfully.", oVO.File2))
  87.         End If
  88.     End Sub
  89.  
  90.     'Thread to process files
  91.     Private Sub ProcessThread(ByVal Args As Object)
  92.         While True
  93.             'Tell our thread to wait here until flagged to process
  94.             ContinueProcess.WaitOne()
  95.             Dim CurrentFile As String = ProcessQueue.Peek
  96.             'Send the data to the verification thread
  97.             Dim oVO As New BinaryCompareObject
  98.             Dim oFileInfo As New FileInfo(CurrentFile)
  99.             oVO.File1 = InputDirectory & "\" & oFileInfo.Name
  100.             oVO.File2 = OutputDirectory & "\" & oFileInfo.Name
  101.             'Copy file
  102.             System.IO.File.Copy(oVO.File1, oVO.File2)
  103.             'Spin off thread to verify copy
  104.             Dim oVerify As New Thread(AddressOf VerifyThread)
  105.             oVerify.Start(oVO)
  106.             SyncLock ProcessQueue
  107.                 ProcessQueue.Dequeue()
  108.                 If ProcessQueue.Count = 0 Then
  109.                     'Process queue has been emptied, so tell this
  110.                     'thread to wait on the next cycle until there
  111.                     'are more files to process.  There's no point
  112.                     'in spinning our wheels.
  113.                     ContinueProcess.Reset()
  114.                 End If
  115.             End SyncLock
  116.             If StopProcessingFlag Then Exit While
  117.         End While
  118.     End Sub
  119.  
  120.     'Adds new and changed files to the process queue for processing
  121.     Private Sub AddFileToProcessQueue(ByVal FilePath As String)
  122.         'Don't bother trying to add the file to the process
  123.         'queue until we can get an exclusive lock.  If you do
  124.         'you'll find your application failing because the file
  125.         'is locked until editing is complete.
  126.         Dim Timeout As Integer = 20
  127.         If FileLock(FilePath, Timeout) Then
  128.             'Don't lock the queue any longer than necessary, or 
  129.             'you'll hinder performance of your application
  130.             SyncLock ProcessQueue
  131.                 If Not ProcessQueue.Contains(FilePath) Then
  132.                     ProcessQueue.Enqueue(FilePath)
  133.                     ContinueProcess.Set()
  134.                 End If
  135.             End SyncLock
  136.         Else
  137.             WriteEntryToLog(String.Format("Unable to gain exclusive lock on {0} for {1} seconds. Copy failed", FilePath, Timeout))
  138.         End If
  139.     End Sub
  140.  
  141.     'This is the event that is fired by our FileSystemWatcher object
  142.     Private Sub FileSystemEvent(ByVal Sender As Object, ByVal e As FileSystemEventArgs)
  143.         AddFileToProcessQueue(e.FullPath)
  144.     End Sub
  145.  
  146.     Sub Main()
  147.         'Set up our process thread so that it's ready to run when our watcher starts
  148.         Dim oProcessThread As New Thread(AddressOf ProcessThread)
  149.         oProcessThread.Start()
  150.         'Set up the file watcher to monitor our input directory.  Add handlers so that
  151.         'when a file is changed or added, it will trigger our FileSystemEvent handler.
  152.         oWatcher = New System.IO.FileSystemWatcher(InputDirectory)
  153.         AddHandler oWatcher.Changed, AddressOf FileSystemEvent
  154.         AddHandler oWatcher.Created, AddressOf FileSystemEvent
  155.         oWatcher.EnableRaisingEvents = True
  156.         'Hold our console window open so we can view the log.
  157.         Console.ReadLine()
  158.     End Sub
  159. End Module
Attached Files
File Type: txt Module1.vb.txt (6.6 KB, 327 views)
Apr 1 '08 #7
Thanks you so much balabaster;

This code sample is really helpful for my requirement, and also helped me to optimise my existing code as well :)

Continuing this, im little bit confused about the locking states, as my process would need mainly 2 threads; on for writing in the queue when file is created and the second one will read the queue and copy to the destination.

Now i want that the Thread or FileWatcher should write the queue the moment its created and don't have to wait for any lock to be released as i think in this case it would missed out some files while waiting. It should be Asynchronous?

About the Reader or Copier; then that should read only when a file is copied completely. (You have used SyncLock for both Writing and Reading)

Also about the FileWatcher Created Event, if i copy a big sized file then it would be raised on the creation of the file or when file is completely copied?

Pleasssssseeeeeeeeeeee Suggest.......
Apr 1 '08 #8
balabaster
797 Expert 512MB
Continuing this, im little bit confused about the locking states, as my process would need mainly 2 threads; on for writing in the queue when file is created and the second one will read the queue and copy to the destination.
Yes, locking is confusing to start with, but it makes more sense after you've used it a few times. Let's pull apart the ProcessThread method to get to grips with what it's doing: Skip down the code until you get to the line SyncLock ProcessQueue.

What we are doing here is telling the application that no other threads can write to the queue until we've finished what we are doing in this block. So...the first line dequeues the file we just finished with and we want to now check to see if the queue is empty so we know whether or not to stop our thread. So we check the queue length and it's zero...we know to pause our thread so it's not spinning its wheels and then we come out of the synclock meaning that other threads can now write to the queue again. In the meantime, the AddFileToProcessQueue method tries to write a new file to the queue. When it tries to write to the queue, the queue object tells it that it must wait, so the AddFileToProcessQueue sits and waits until the queue unlocks at which point it carries on with what it was doing in the first place.

So what happens when we remove the synclock? Imagine the same scenario again, except we don't lock the queue. We dequeue the file we just finished with and count the items in the queue. There's no items in the queue. Sometime between dequeueing the item, but before we process the next line of code in this thread (which sets our pause state), the other thread writes a file to the queue and sets the continue flag which would normally tell the process thread to continue processing on it's next loop. But now this thread sets the pause state and we restart our loop and pause waiting. So now our thread sits doing nothing until another file is written to the queue, even though there is one sitting waiting already.

I haven't checked to be 100% sure of this, but I'm fairly certain (but I've been wrong in the past):
Try removing the SyncLock from the queuing process and run the application. The first time the Queueing thread tries to write to the queue while the Processing thread has it locked, your application will crash. Both sides must use the SyncLock in order for it to work correctly. So in order to SyncLock on read, you must also SyncLock on write.

Now i want that the Thread or FileWatcher should write the queue the moment its created and don't have to wait for any lock to be released as i think in this case it would missed out some files while waiting. It should be Asynchronous?
If you wanted to spin the queueing process off to a new thread instead of having the the synchronous example we had, you could change the parameters of the AddFileToProcessQueue and change the method call slightly:
Expand|Select|Wrap|Line Numbers
  1. Private Sub AddFileToProcessQueue(ByVal Args As Object)
  2.   Dim FilePath As String = CType(Args, String)
  3.   'Continue with the rest of the code that was previously here...
  4. End Sub
  5.  
  6. Private Sub FileSystemEvent(ByVal Sender As Object, ByVal e As FileSystemEventArgs)
  7.   Dim oQueueThread As New Thread(AddressOf AddFileToProcessQueue)
  8.   oQueueThread.Start(e.FullPath)
  9. End Sub
If you do this though, you will definitely have to keep the SyncLock otherwise you're going to end up with many threads all trying to write to the queue while your process thread is trying to clear it and your application will end up with all sorts of deadlock situations.

About the Reader or Copier; then that should read only when a file is copied completely. (You have used SyncLock for both Writing and Reading)
The file will not be able to be copied until it is finished writing to the file system. The "Changed" and "Created" events occur immediately someone hits save or as the file object is initially created on the file system. So if for example a large file is being copied into your input directory and you immediately try to process it, the process will fail - hence the need for the ExclusiveLock process. You can verify if we could check for an exclusive lock at one of two logical points...either during the course of the process thread or when we queue the file up. In the example I posted, we checked before we queued the file up, but you could queue it up blindly and then verify right before it's copied - which might make more sense depending on the situation. I prefer to check before I queue it as I don't want to have my process thread spinning it's wheels waiting for a file that may waste time waiting to timeout.

Also about the FileWatcher Created Event, if i copy a big sized file then it would be raised on the creation of the file or when file is completely copied?
It's raised on creation, not once copy is complete. Hence the missing files you've probably noticed....also, when you create a new file, it raises the created event and a bunch of changed events. You will only be able to get an exclusive lock once the final changed event has fired. The only problem is - there is no way to find out how many times the event will fire for any given file. It might fire only once, it might fire 4 times, it may only fire twice. There doesn't seem to be any rhyme or reason for how many times the changed event fires except that it fires at least once for all file changes and creations. You don't really want to queue the same file up many times unecessarily, so the best way I know is to check for an exclusive lock prior to queuing the file up.
Apr 1 '08 #9
Again a lot of thanks for the detailed answer that cleared many issues.
Now i'm ok with the Exclusive Lock.

Kindly explain this scenario, when a file is created, FileWatcher fired the event and my Process Thread adds it to Queue and also locks the Queue; Now meanwhile another file is created and that will also wait for the lock to be released and so on some new files are also there.

Kindly Tell me;

1 - All the new files that are created during the Queue is locked by FileWatcher will be queued in the wait state?

2 - All these will be separated in threads?

3 - Is there any possibility that during this wait time (when a file is already being written in the queue) my process could miss a newly created file?

I'm very much concerned about the accuracy and perfection as i need to make sure about each scenario.

Again Thank you very much for the detailed examples.
Apr 1 '08 #10
balabaster
797 Expert 512MB
1 - All the new files that are created during the Queue is locked by FileWatcher will be queued in the wait state?
Due to the manner in which we are now spinning off a new thread to add items to the queue each time the FileSystemWatcher flags a file, you shouldn't miss any files. The process order is this:
  • The FileProcess thread is started up and put into a paused state waiting for files to process.
  • FileSystemWatcher sees a file has been added and/or changed
  • FileSystemWatcher spins off a new thread that adds the new/changed file to the process queue and immediately goes back to listening for the next file change.
  • Meanwhile the new queue that was spun off to add the file to the queue now may or may not be in a wait state to add the file to the queue. It may add it immediately, or it may have to wait...but either way, this happens asynchronously to the FileSystemWatcher listening for changes. Once it has added the file to the queue, it updates the processing flag to allow the FileProcess thread to go about processing items in the queue and ends.
  • The ProcessThread receives the notification to process items in the queue. As it processes each item in the queue it removes them and then spins off another thread to verify the file contents asynchronously while it goes back to process other items in the queue or wait for new items to be added to the queue.
So as you see, there is never a point where the FileSystemWatcher is hung up waiting for the ProcessQueue so it can write. Every new/changed file spins off a new thread that does the waiting/writing to the queue, so that it can go back to doing what it does best...hanging out waiting for file changes.
2 - All these will be separated in threads?
I guess I already answered this one...every new/changed file spins off a new thread. So it's completely asynchronous.
3 - Is there any possibility that during this wait time (when a file is already being written in the queue) my process could miss a newly created file?
I had the same concern when I originally developed this code for an application for my company, it's been running for the past 9 months without a single hiccup. The ProcessThread in the code for my application is significantly more complex than just copying the file from one directory to another though...
Apr 2 '08 #11
Thanks again, its really making my way clear.

According to the Answers now i got some issues while testings;

1 - Is this recommended that when my process is copying/Verifying a file, another user tries to open that file. In that case what would be happened?
a - He gets the "File in Use Error"
b - Should we lock the file during this process instead of before staring it?

2 - In your Process Thread; the verifyThread is started after the copy and when it dies?

3 - I think when we check the File is completely copied through the Exclusive Lock then we don't need the Changed Event of the File Watcher. Correct?

4 - Please give me the syntax of using file watcher in C#, i'm trying it through code instead of form control but the event is not initiated when a file is created.

Thanks again and again.
Apr 2 '08 #12
balabaster
797 Expert 512MB
1 - Is this recommended that when my process is copying/Verifying a file, another user tries to open that file. In that case what would be happened?
a - He gets the "File in Use Error"
b - Should we lock the file during this process instead of before staring it?
a). No, because we are only reading the file to calculate an MD5 hash, it doesn't need to get an exclusive lock. However, if someone opens and resaves the file, the new file and the original file will now have different hashes, so the verification will fail in that sense.
b). You could open the file exclusively at the start of your verification process to prevent anyone changing the file prior to the verification completion. This would prevent a scenario such as that.

2 - In your Process Thread; the verifyThread is started after the copy and when it dies?
The verify thread dies once it has finished verifying the file...the process thread continuously loops unless we set the StopProcessing flag to exit that thread.

3 - I think when we check the File is completely copied through the Exclusive Lock then we don't need the Changed Event of the File Watcher. Correct?
If you don't use the changed flag and a file that already previously exists in your input directory is changed, then it won't be copied. Only newly created files will be copied.

4 - Please give me the syntax of using file watcher in C#, i'm trying it through code instead of form control but the event is not initiated when a file is created.
Expand|Select|Wrap|Line Numbers
  1. FileSystemWatcher oWatcher = new System.IO.FileSystemWatcher("NameOfDirectoryToWatch", "FilterString");
NameOfDirectoryToWatch is a string value specifying the path of the directory to watch
FilterString is an optional string value that tells the FileSystemWatcher what type of files to look for. It works exactly the same as the directory filter when you type "dir" at the command prompt: *.* = all files; *.pdf = all pdf files etc. You can semi-colon delimit this.
The IncludeSubDirectories property of the FileSystemWatcher is a boolean value (true/false) that specifies whether or not to watch sub directories of your main directory or not.
Apr 2 '08 #13
I'm Ok with the rest of issues. Actually these files are audio files so the modification is not possible there, one can only listen them. So thats why i was looking for only Created Event.

About the FileWatcher in C#, im having problem to initialize it and handled its event but its not working may be im missing something;

Heres the Code;

Expand|Select|Wrap|Line Numbers
  1.     class SourceFileWatcher
  2.     {
  3.  
  4.         private FileSystemWatcher fileWatcher;
  5.  
  6.         public SourceFileWatcher(string sourceDir, string fileFilter)
  7.         {
  8.             this.fileWatcher = new FileSystemWatcher(sourceDir, fileFilter);
  9.             this.fileWatcher.Created += new FileSystemEventHandler(this.fileWatcher_Created);
  10.             this.fileWatcher.EnableRaisingEvents = true;
  11.         }
  12.  
  13.         public void fileWatcher_Created(Object sender, FileSystemEventArgs e)
  14.         {
  15.             Console.WriteLine("File is Created:");        
  16.         }
  17.     }
  18.  
  19.  
  20.  
  21.     class Program
  22.     {
  23.  
  24.         static void Main()
  25.         {
  26.                 Program prg = new Program();
  27.  
  28.                 SourceFileWatcher sf = new SourceFileWatcher(InputDir, filter);
  29.  
  30.                 Console.ReadLine();
  31.          }
  32.  
  33.  
Now when the file is created on the source path then the event is not generated. Kindly let me know what i am missing here.
Thanks a lot.
Apr 2 '08 #14
balabaster
797 Expert 512MB
Here's the C# code which does exactly the same but in some areas (particularly the date comparison in the FileLock method) slightly differently. I've also attached the CS file - just like the VB file before, just remove the .txt extension to use it as a module in your code:
Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Security.Cryptography;
  3. using System.Text;
  4. using System.IO;
  5. using System.Threading;
  6. using System.Collections.Generic;
  7. namespace FileCopierClass
  8. {
  9.     class BinaryCopyObject
  10.     {
  11.         private string _File1;
  12.         private string _File2;
  13.         #region Properties
  14.             public string File1 { 
  15.                 get
  16.                 {
  17.                     return _File1;
  18.                 }
  19.                 set
  20.                 {
  21.                     _File1 = value;
  22.                 }
  23.             }
  24.             public string File2 {
  25.                 get
  26.                 {
  27.                     return _File2;
  28.                 }
  29.                 set
  30.                 {
  31.                     _File2 = value;
  32.                 }
  33.             }
  34.         #endregion
  35.         #region Methods
  36.             public static bool Compare(string File1, string File2)
  37.             {
  38.                 MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
  39.                 md5.ComputeHash(File.ReadAllBytes(File1));
  40.                 Byte[] hash1 = md5.Hash;
  41.                 md5.ComputeHash(File.ReadAllBytes(File2));
  42.                 Byte[] hash2 = md5.Hash;
  43.                 return (Convert.ToBase64String(hash1) == Convert.ToBase64String(hash2));
  44.             }
  45.             public bool IsMatch()
  46.             {
  47.                 return Compare(_File1, _File2);
  48.             }
  49.         #endregion
  50.     }
  51.     class Program
  52.     {
  53.         private static string InputDirectory = "C:\\AppTesting\\Input";
  54.         private static string OutputDirectory = "C:\\AppTesting\\Output";
  55.         private static ManualResetEvent ContinueProcess = new ManualResetEvent(false);
  56.         private static Queue<string> ProcessQueue = new Queue<string>();
  57.         private static FileSystemWatcher oWatcher = new FileSystemWatcher();
  58.         private static bool StopProcessingFlag = false;
  59.         private static void WriteEntryToLog(string LogEntry)
  60.         {
  61.             Console.WriteLine(LogEntry);
  62.         }
  63.         private static bool FileLock(string FilePath, int TimeOut)
  64.         {
  65.             DateTime StartTime = DateTime.Now;
  66.             while (true)
  67.             {
  68.                 TimeSpan ts = DateTime.Now - StartTime;
  69.                 if ((TimeOut > 0) && (ts.Seconds > TimeOut)) { break; }
  70.                 try
  71.                 {
  72.                     FileStream oStrm = File.OpenWrite(FilePath);
  73.                     oStrm.Close();
  74.                     oStrm.Dispose();
  75.                     return true;
  76.                 }
  77.                 catch { }
  78.                 Thread.Sleep(0);
  79.             }
  80.             return false;
  81.         }
  82.         static void VerifyThread(object args)
  83.         {
  84.             BinaryCopyObject oVO = (BinaryCopyObject)args;
  85.             if (!oVO.IsMatch())
  86.             {
  87.                 WriteEntryToLog(string.Format("{0} copy wasn't successful. Deleting and retrying.", oVO.File1));
  88.                 File.Delete(oVO.File2);
  89.                 AddFileToProcessQueue(oVO.File1);
  90.             }
  91.             else
  92.             {
  93.                 WriteEntryToLog(string.Format("{0} copied and verified successfully.", oVO.File2));
  94.             }
  95.         }
  96.         static void ProcessThread() 
  97.         {
  98.             ContinueProcess.WaitOne();
  99.             string CurrentFile = ProcessQueue.Peek();
  100.             BinaryCopyObject oVO = new BinaryCopyObject();
  101.             FileInfo oFileInfo = new FileInfo(CurrentFile);
  102.             oVO.File1 = InputDirectory + "\\" + oFileInfo.Name;
  103.             oVO.File2 = OutputDirectory + "\\" + oFileInfo.Name;
  104.  
  105.             File.Copy(oVO.File1, oVO.File2);
  106.             Thread oVerify = new Thread(VerifyThread);
  107.  
  108.             oVerify.Start(oVO);
  109.             lock (ProcessQueue)
  110.             {
  111.                 ProcessQueue.Dequeue();
  112.                 if (ProcessQueue.Count == 0)
  113.                 {
  114.                     ContinueProcess.Reset();
  115.                 }
  116.             }
  117.             if (StopProcessingFlag)
  118.             {
  119.                 return;
  120.             }
  121.         }
  122.         private static void AddFileToProcessQueue(string FilePath)
  123.         {
  124.             int TimeOut = 20;
  125.             if (FileLock(FilePath, TimeOut))
  126.             {
  127.                 lock (ProcessQueue)
  128.                 {
  129.                     if (!ProcessQueue.Contains(FilePath))
  130.                     {
  131.                         ProcessQueue.Enqueue(FilePath);
  132.                         ContinueProcess.Set();
  133.                     }
  134.                 }
  135.             }
  136.             else
  137.             {
  138.                 WriteEntryToLog(string.Format("Unable to gain exclusive lock on {0} for {1} seconds. Copy failed", FilePath, TimeOut));
  139.             }
  140.         }
  141.         private static void FileSystemEvent(object sender, FileSystemEventArgs e)
  142.         {
  143.             AddFileToProcessQueue(e.FullPath);
  144.         }
  145.         static void Main(string[] args)
  146.         {
  147.             Thread oProcessThread = new Thread(new ThreadStart(ProcessThread));
  148.             oProcessThread.Start();
  149.             FileSystemWatcher oWatcher = new FileSystemWatcher(InputDirectory);
  150.             oWatcher.Changed += new FileSystemEventHandler(FileSystemEvent);
  151.             oWatcher.Created += new FileSystemEventHandler(FileSystemEvent);
  152.             oWatcher.EnableRaisingEvents = true;
  153.             Console.ReadLine();
  154.         }
  155.     }
  156. }
Don't forget that when you're accessing class level variables and other methods from methods defined as static, that the objects they are referencing must also be declared as static...
Attached Files
File Type: txt Program.cs.txt (5.4 KB, 366 views)
Apr 2 '08 #15
Thanks a loooooooooooooooooooottttttttttttttttttt
I must say you really have become the source of knowledge for me in this task. This is exceptional support.

I was having some problems with the conversions and its so good that you gave me the converted version. Thanks again :P

Some change i want to mention that i made in my application;

1 - The final product will be the window service. If you can give me some recommendations and precautions for this then it would be great.

2 - in your code

Expand|Select|Wrap|Line Numbers
  1. TimeSpan ts = DateTime.Now - StartTime;
  2.                 if ((TimeOut > 0) && (ts.Seconds > TimeOut)) { break; }
  3.  
I think we should use the "ts.TotalSeconds"?

3 - I have made another queue for the Verifier Thread. As i dont want to generate a new thread on each copy, so whenever a copy is made it enters in the verify queue to be verified. Please suggest what is best?


Again very much thanks to you :)
Apr 3 '08 #16
balabaster
797 Expert 512MB
1 - The final product will be the window service. If you can give me some recommendations and precautions for this then it would be great.
This is the perfect scenario for a Windows Service. I would say that it's a pretty easy transfer from a Console Application into a Windows Service. Take the code from the Main() method and put it into the OnStart() method. Make sure in the OnStop() method you set the flag to that ends your process and verify threads and you dispose of your FileSystemWatcher.
2 - in your code
Expand|Select|Wrap|Line Numbers
  1. TimeSpan ts = DateTime.Now - StartTime;
  2. if ((TimeOut > 0) && (ts.Seconds > TimeOut)) { break; }
  3.  
I think we should use the "ts.TotalSeconds"?
As your timeout is always likely to be less than 1 minute, it doesn't matter that we are using Seconds vs. TotalSeconds. When your timespan is greater than 1 minutes, say...1 minute 45 seconds, seconds holds the value 45, whereas total seconds holds 105. I would doubt you would set a timeout greater than 1 minute, so in this case I would say that both will function the same.
3 - I have made another queue for the Verifier Thread. As i dont want to generate a new thread on each copy, so whenever a copy is made it enters in the verify queue to be verified. Please suggest what is best?
Good stuff - that will preserve thread resources. Don't forget if you do this that you must set a flag the same as we did in the process thread so that you can stop it in a controlled fashion when you bring the service down.
Again very much thanks to you :)
No problem
Apr 3 '08 #17
Ok, thats really great.

Thanks a lot :)
Apr 3 '08 #18

Sign in to post your reply or Sign up for a free account.

Similar topics

0
by: Paul Rushton | last post by:
When I run the application verifier against almost any project in VB.NET the same two errors come up. I've tried searching the net but I cannot find a thing about it. I have installed the latest...
0
by: SkySea | last post by:
Hi! Any help on this would be appreciated... In an HTML document that lists instructions on installing some software, there's a point where a DOS batch file needs to be run in order to copy...
0
by: + Kennedy Kok + | last post by:
I ran my C# application under Application Verifier 2.50 with the test for Handles checked. My application fails - and application verifier reports that that i am passing an invalid handle. The...
12
by: Anders Eriksson | last post by:
Hello! I'm trying to create a program that will watch a directory and when a file is created print that file. I have used FileSystemWatcher for watching the directory and I get an created event....
2
by: Itjalve | last post by:
I have a heap problem in my com exe server. When i use windbg as the compiler in application verifier is windbg started and i can press 'g' and the server is running unitil i get the exception. ...
0
by: maitrepoy | last post by:
Hello I have to create a small addin which works on Powerpoint, Word, Outlook, and Excel on Office 2000, XP, and 2003. This addin consists in adding 2 new Buttons in the "File" Menu of office....
4
by: vvenk | last post by:
Hello: I have an ASP application that takes a file and parses it. I have a fileUpload control on my ASP page. Here's the code that gets file details: Dim srFile As StreamReader Try srFile...
0
by: NickP | last post by:
Hi there, What is the easiest way to get application verifier working with a VB.NET project? Currently I do not appear to be able to launch the application in VS 2005 with the verifier...
6
by: ivan.perak | last post by:
Hello, im a beginner in VB.NET... The thing i would like to do is as it follows.... I have a text file (list of names, every name to the next line) which is about 350000 lines long. I would...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.