Working with FileSystemWatcher Class
Hey, if you are here to find the answer of this question "how to make sure in Created event of the Filewatcher that the file which is just created is completely copied?" then you are at the right place..
FileSystemWatcher class listens to the file system change notification and raises events when a directory, or file in a directory, changes.. In this article I’ll discuss
fileSystemWatcher1_Created(object sender, FileSystemEventArgs e) event of FileSystemWatcher class. Working with this event is easy. You just need to capture this event and then write your code in it. BUT there is a problem in this event which is that the Created event is fired immediately as soon as the path of the file is created in the observing directory. This can be clearly explained with the help of a following scenario: I want to observe a Directory say C:\\Test. I wrote a window service which uses the FileSystemWatcher class to observe that directory. I want to pass any new file which is created in this directory to another method which processes this file. Suppose my file’s size is large (e.g. 500mb). In my window service the Created event of the FileSystemWatcher is triggered as soon as the file’s path is created in the directory, but file is not copied completely in the directory. How to solve this issue? .Net does not provide any method or event which can tell me that the file is written completely. I tried to solve this problem and though I achieved my task, but this is not a good solution. In the Created event I made a thread. So for each new file a new thread will be created, so we can serve each new file without any delay. In that particular thread, I tried to open the file. If file is opened successfully, then it means that file is copied completely and is available for processing. If not, then try to open the file again. Repeat this process until the file is available. Here is the code:
void fileSystemWatcher1_Created(object sender, FileSystemEventArgs e)
{
Thread _MyThread = new Thread(new ParameterizedThreadStart(this.PerformActualTask));
object[] Parameters = new object[] {e. FullPath };
_MyThread.Start(Parameters);
}
private void PerformActualTask(object parameters)
{
//The parameter for this thread body
object[] Parameters = (object[])parameters;
//Full path of the newly created file
string _SourceFile = (string)Parameters[0];
int WaitBeforeGiveUp = 300;
while (true)
{
try
{
//Try to open the file
FileStream fs = File.Open(_SourceFile, FileMode.Open);
{
//We are here because file is successfully opened
fs.Close();
//Now perform operation on that file
}
}
catch (Exception ex)
{
//If exception occured then decriment the wait before give up and ask the thread to sleep
if (--WaitBeforeGiveUp > 0)
{
// file is not available yet
}
else
{
//if waiting time expired.
// SHOW GIVE UP MESSAGE
} //cause the thread to sleep
Thread.Sleep(1000);
}
}
}
In the code I made some changes which are that I tried to open a file for a particular period of time. If file opened in that period then kool, else I stored a msg in the event viewer that I have given up.