I need to create a C# Console Application that will parse the file from SFTP directory when the new file created. For that I implemented FileSystemWatcher with FileCreated event which enqueue the new file path and create a new thread and parse the file.
I read in the blogs that some times FileSystemWatcher may fail to detect new files, for that I implemented Timer which will fire every 1 hr and if the FileSystemWatcher thread is in waitsleep state then will read the IMCOMING SFTP folder and parse the file.
Below is the code i written for FileSystemWatcher and Timer, but its not working properly and I think filesystemwatcher is not in Multithreading. Please help me to get right solution.
MAIN
static void Main(string[] args)
{
try
{
string path = incomingFilePath;
if (Directory.Exists(path))
{
#region Initiate Timer
Thread t = new Thread(new ParameterizedThreadStart(ThreadLoop));
t.Start((Action)fileProcessor.StartTimer);
#endregion
#region FileSystemWatcher
watcher = new FileSystemWatcher { Path = path, Filter = "*.CUST", IncludeSubdirectories = true };
watcher.Created += new
FileSystemEventHandler(watcher_FileCreated);
watcher.Error += new
ErrorEventHandler(watcher_OnError);
watcher.EnableRaisingEvents = true;
#endregion
}
}
catch (Exception Err)
{
}
}
FILESYSTEMWATCHER CODE:
private static void watcher_FileCreated(object sender, FileSystemEventArgs e)
{
if (e.FullPath.ToUpper().Contains("INCOMING"].ToString()))
{
fileProcessor.EnqueueFile(e.FullPath);
lock (lockObject)
{
files.Enqueue(path);
}
if (FileWacherThread == null || shouldStop)
{
FileWacherThread = new Thread(new ThreadStart(Work));
FileWacherThread.Start();
}
// If the thread is waiting then start it
else if (FileWacherThread.ThreadState == ThreadState.WaitSleepJoin)
{
waitHandle.Set();
}
}
}
private void Work()
{
while (!shouldStop)
{
string path = String.Empty;
lock (lockObject)
{
if (files.Count > 0)
{
path = files.Dequeue();
}
}
if (!String.IsNullOrEmpty(path))
{
// Process the file
ParseFile(path);
}
else
{
// If no files are left to process then wait
waitHandle.WaitOne();
}
}
}
TIMER CODE
public void StartTimer()
{
lock (lockObject)
{
if (FileWacherThread == null || FileWacherThread.ThreadState == ThreadState.WaitSleepJoin)
{
if (files.Count == 0)
{
IEnumerable<string> result = new List<string>(Directory.GetFiles(incomingFilePath, "*.CUST", SearchOption.AllDirectories)).Where(s => s.Contains(incomingFilePrefix));
foreach (string path in result)
{
ParseFile(path);
}
}
}
}
}
Things to check...
is waitHandle
an AutoResetEvent
or a ManualResetEvent
? (from the way that you are using it, it should be an AutoResetEvent
If shouldStop
is true
, is FileWacherThread
(sic) set to null
when Work()
exits...
How are you protecting access to FileWacherThread
? if it is accessed from multiple threads (to check its state, assign etc, then it too should be protected with a lock).
You shouldn't worry about the state of the FileWacherThread
when you set the event. If you want to signal to that thread, just set it, (ie build your multithreaded code such that the publisher doesn't know/care about the current state of the subscriber). Currently there are states that your FileWacherThread
can be in where it isn't waiting but it might still need to be signaled. If you always set the event, the worst that can happen is that it loops one time unnecessarily.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.